Skip to content

Commit

Permalink
Fix types on createReadOnly option of snapshotted views
Browse files Browse the repository at this point in the history
  • Loading branch information
thegedge committed Jul 4, 2024
1 parent 3dea56c commit ecf3c59
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
35 changes: 32 additions & 3 deletions spec/types.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
/* eslint-disable @typescript-eslint/consistent-type-imports */
import type { Has, IsExact } from "conditional-type-checks";
import { assert } from "conditional-type-checks";
import { SnapshotIn, TypesForModelPropsDeclaration, action, register } from "../src";
import { IMaybeNullType, INodeModelType, IOptionalType, ISimpleType, types } from "../src";
import {
ClassModel,
IMaybeNullType,
INodeModelType,
IOptionalType,
ISimpleType,
SnapshotIn,
TypesForModelPropsDeclaration,
action,
register,
snapshottedView,
types,
} from "../src";
import { NamedThingClass, TestClassModel } from "./fixtures/TestClassModel";
import { NamedThing, TestModel } from "./fixtures/TestModel";

Expand Down Expand Up @@ -61,7 +72,7 @@ describe("SnapshotIn", () => {
return "hello";
}
@action
mixinAction(value: string) {
mixinAction(_value: string) {
// empty
}
}
Expand All @@ -77,4 +88,22 @@ describe("SnapshotIn", () => {
assert<IsExact<Actual["optional"], string | undefined>>(true);
assert<Has<keyof Actual, "mixinView">>(false);
});

test("works on class models with snapshotted views", () => {
@register
class DataContainer extends ClassModel({ id: types.identifier }) {}

@register
class DataMap extends ClassModel({ stuff: types.map(DataContainer) }) {}

@register
class _SnapshottedViewClass extends TestClassModel {
@snapshottedView<typeof DataMap>({
createReadOnly: (value) => DataMap.createReadOnly(value),
})
get test() {
return DataMap.createReadOnly();
}
}
});
});
17 changes: 10 additions & 7 deletions src/class-model.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import "reflect-metadata";

import memoize from "lodash.memoize";
import type { Instance, IModelType as MSTIModelType, ModelActions } from "mobx-state-tree";
import { comparer, reaction, type IReactionDisposer } from "mobx";
import type { IModelType as MSTIModelType, ModelActions } from "mobx-state-tree";
import { types as mstTypes } from "mobx-state-tree";
import { RegistrationError } from "./errors";
import { InstantiatorBuilder } from "./fast-instantiator";
import { FastGetBuilder } from "./fast-getter";
import { InstantiatorBuilder } from "./fast-instantiator";
import { defaultThrowAction, mstPropsFromQuickProps, propsFromModelPropsDeclaration } from "./model";
import { getSnapshot } from "./snapshot";
import {
$context,
$identifier,
Expand All @@ -26,13 +28,13 @@ import type {
IAnyType,
IClassModelType,
IStateTreeNode,
Instance,
ModelPropertiesDeclaration,
ModelViews,
SnapshotIn,
TypesForModelPropsDeclaration,
} from "./types";
import { cyrb53 } from "./utils";
import { comparer, reaction, type IReactionDisposer } from "mobx";
import { getSnapshot } from "./snapshot";

/** @internal */
type ActionMetadata = {
Expand All @@ -42,12 +44,12 @@ type ActionMetadata = {
};

/** Options that configure a snapshotted view */
export interface SnapshottedViewOptions<V, T extends IAnyClassModelType> {
export interface SnapshottedViewOptions<ViewReturnT, ParentNodeT extends IAnyClassModelType> {
/** A function for converting a stored value in the snapshot back to the rich type for the view to return */
createReadOnly?: (value: V | undefined, node: Instance<T>) => V | undefined;
createReadOnly?: (value: SnapshotIn<ViewReturnT> | undefined, node: Instance<ParentNodeT>) => Instance<ViewReturnT> | undefined;

/** A function for converting the view value to a snapshot value */
createSnapshot?: (value: V) => any;
createSnapshot?: (value: ViewReturnT) => any;

/** A function that will be called when the view's reaction throws an error. */
onError?: (error: any) => void;
Expand All @@ -74,6 +76,7 @@ export type VolatileMetadata = {
};

type VolatileInitializer<T> = (instance: T) => Record<string, any>;

/** @internal */
export type PropertyMetadata = ActionMetadata | ViewMetadata | SnapshottedViewMetadata | VolatileMetadata;

Expand Down

0 comments on commit ecf3c59

Please sign in to comment.