@plasmicapp/react-web 0.2.140 → 0.2.141

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,12 +6,16 @@ export interface StateCell<T> {
6
6
  listeners: (() => void)[];
7
7
  }
8
8
  export declare class StateSpecNode<T> {
9
- private specs;
10
- private edges;
11
- private state;
9
+ private _specs;
10
+ private _edges;
11
+ private _state;
12
12
  constructor(specs: Internal$StateSpec<T>[]);
13
+ setSpecs(specs: Internal$StateSpec<T>[]): void;
14
+ edges(): Map<string | symbol, StateSpecNode<any>>;
15
+ state(): Record<string, StateCell<T>>;
13
16
  hasEdge(key: string | symbol): boolean;
14
17
  addEdge(key: string | symbol, node: StateSpecNode<any>): void;
18
+ clearEdges(): void;
15
19
  children(): IterableIterator<StateSpecNode<any>>;
16
20
  makeTransition(key: string | symbol | number): StateSpecNode<any> | undefined;
17
21
  isLeaf(): boolean;
@@ -19,6 +23,7 @@ export declare class StateSpecNode<T> {
19
23
  getSpec(): Internal$StateSpec<T>;
20
24
  getAllSpecs(): Internal$StateSpec<T>[];
21
25
  getState(path: ObjectPath): StateCell<T>;
26
+ getInitFunc(stateCell: StateCell<any>): InitFunc<any> | undefined;
22
27
  clearStates(): void;
23
28
  states(): StateCell<T>[];
24
29
  hasState(path: ObjectPath): boolean;
@@ -29,7 +34,8 @@ export declare class StateSpecNode<T> {
29
34
  }
30
35
  export declare const transformPathStringToObj: (str: string) => (string | symbol)[];
31
36
  export declare function buildTree(specs: $StateSpec<any>[]): StateSpecNode<any>;
32
- export declare function getLeaves(root: StateSpecNode<any>): StateSpecNode<any>[];
37
+ export declare function updateTree(root: StateSpecNode<any>, specs: $StateSpec<any>[]): StateSpecNode<any>;
38
+ export declare function getStateCells(root: StateSpecNode<any>): StateSpecNode<any>[];
33
39
  export declare function findStateCell(root: StateSpecNode<any>, pathStr: string, repetitionIndex?: number[]): {
34
40
  node: StateSpecNode<any>;
35
41
  realPath: ObjectPath;
@@ -1,16 +1,14 @@
1
1
  import { useLayoutEffect } from "react";
2
- import { $State } from "./types";
3
- export declare function generateStateOnChangeProp($state: $State, stateName: string, dataReps: number[]): (val: any, path: (string | number)[]) => void;
4
- /**
5
- * This function generate the state value prop for repeated states
6
- * Example:
7
- * - parent[][].counter[].count
8
- * We need to pass `parent[index1][index2].counter to the child component
9
- */
10
- export declare function generateStateValueProp($state: $State, path: (string | number)[]): any;
2
+ import { $State, ObjectPath } from "./types";
3
+ export declare function generateStateOnChangeProp($state: $State, path: ObjectPath): (val: any) => void;
4
+ export declare function generateStateValueProp($state: $State, path: ObjectPath): any;
11
5
  export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
12
6
  export declare function isPlasmicStateProxy(obj: any): any;
13
7
  export declare function shallowEqual<T>(a1: T[], a2: T[]): boolean;
8
+ /**
9
+ * Shallow comparison of arrays.
10
+ */
11
+ export declare function arrayEq(xs: ReadonlyArray<any>, ys: ReadonlyArray<any>): boolean;
14
12
  export declare function isNum(value: string | number | symbol): value is number;
15
13
  declare type StringGen = string | (() => string);
16
14
  export declare function assert<T>(cond: T, msg?: StringGen): asserts cond;
@@ -1,3 +1,5 @@
1
1
  import { $State, $StateSpec } from "./types";
2
- export declare function useDollarState(specs: $StateSpec<any>[], props: Record<string, any>, $ctx?: Record<string, any>): $State;
2
+ export declare function useDollarState(specs: $StateSpec<any>[], props: Record<string, any>, $ctx?: Record<string, any>, opts?: {
3
+ inCanvas: boolean;
4
+ }): $State;
3
5
  export default useDollarState;
@@ -43,6 +43,12 @@ export declare const InitFuncFromRootContextData: import("@storybook/csf").Annot
43
43
  name: string;
44
44
  }[];
45
45
  }>;
46
+ export declare const InitFuncFromInternalContextDataWithDelay: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, {
47
+ products: {
48
+ price: number;
49
+ name: string;
50
+ }[];
51
+ }>;
46
52
  export declare const RepeatedImplicitState: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, {}>;
47
53
  interface Person {
48
54
  firstName: string;
@@ -62,3 +68,4 @@ export declare const IsOnChangePropImmediatelyFired: import("@storybook/csf").An
62
68
  export declare const ImmutableStateCells: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, {
63
69
  people: Person[];
64
70
  }>;
71
+ export declare const InCanvasDollarState: import("@storybook/csf").AnnotatedStoryFn<import("@storybook/react").ReactFramework, {}>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasmicapp/react-web",
3
- "version": "0.2.140",
3
+ "version": "0.2.141",
4
4
  "description": "plasmic library for rendering in the presentational style",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -109,5 +109,5 @@
109
109
  "react": ">=16.8.0",
110
110
  "react-dom": ">=16.8.0"
111
111
  },
112
- "gitHead": "2ddf7320f54e314e4f44d3df3c50468d2740ddbf"
112
+ "gitHead": "412d7cef82888017b8a4fad4acc87e3e6be13562"
113
113
  }
@@ -670,17 +670,10 @@ function useTrigger(trigger, opts) {
670
670
  var ARRAY_SYMBOL = Symbol("[]");
671
671
  var PLASMIC_STATE_PROXY_SYMBOL = Symbol("plasmic.state.proxy");
672
672
 
673
- function generateStateOnChangeProp($state, stateName, dataReps) {
674
- return function (val, path) { return set($state, __spreadArray(__spreadArray([stateName], __read(dataReps), false), __read(path), false), val); };
673
+ function generateStateOnChangeProp($state, path) {
674
+ return function (val) { return set($state, path, val); };
675
675
  }
676
- /**
677
- * This function generate the state value prop for repeated states
678
- * Example:
679
- * - parent[][].counter[].count
680
- * We need to pass `parent[index1][index2].counter to the child component
681
- */
682
- function generateStateValueProp($state, path // ["parent", 0, 1, "counter"]
683
- ) {
676
+ function generateStateValueProp($state, path) {
684
677
  return get($state, path);
685
678
  }
686
679
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
@@ -698,6 +691,12 @@ function shallowEqual(a1, a2) {
698
691
  }
699
692
  return true;
700
693
  }
694
+ /**
695
+ * Shallow comparison of arrays.
696
+ */
697
+ function arrayEq(xs, ys) {
698
+ return (xs.length === ys.length && xs.every(function (_, index) { return xs[index] === ys[index]; }));
699
+ }
701
700
  function isNum$1(value) {
702
701
  return typeof value === "symbol" ? false : !isNaN(+value);
703
702
  }
@@ -763,68 +762,83 @@ function assignValue(object, key, value) {
763
762
  var UNINITIALIZED = Symbol("plasmic.unitialized");
764
763
  var StateSpecNode = /** @class */ (function () {
765
764
  function StateSpecNode(specs) {
766
- this.specs = specs;
767
- this.edges = new Map();
768
- this.state = {};
765
+ this._specs = specs;
766
+ this._edges = new Map();
767
+ this._state = {};
769
768
  }
769
+ StateSpecNode.prototype.setSpecs = function (specs) {
770
+ this._specs = specs;
771
+ };
772
+ StateSpecNode.prototype.edges = function () {
773
+ return this._edges;
774
+ };
775
+ StateSpecNode.prototype.state = function () {
776
+ return this._state;
777
+ };
770
778
  StateSpecNode.prototype.hasEdge = function (key) {
771
- return this.edges.has(key);
779
+ return this._edges.has(key);
772
780
  };
773
781
  StateSpecNode.prototype.addEdge = function (key, node) {
774
- this.edges.set(key, node);
782
+ this._edges.set(key, node);
783
+ };
784
+ StateSpecNode.prototype.clearEdges = function () {
785
+ this._edges = new Map();
775
786
  };
776
787
  StateSpecNode.prototype.children = function () {
777
- return this.edges.values();
788
+ return this._edges.values();
778
789
  };
779
790
  StateSpecNode.prototype.makeTransition = function (key) {
780
791
  key = isNum$1(key) ? ARRAY_SYMBOL : key;
781
- return this.edges.get(key);
792
+ return this._edges.get(key);
782
793
  };
783
794
  StateSpecNode.prototype.isLeaf = function () {
784
- return this.edges.size === 0;
795
+ return this._edges.size === 0;
785
796
  };
786
797
  StateSpecNode.prototype.hasArrayTransition = function () {
787
- return this.edges.has(ARRAY_SYMBOL);
798
+ return this._edges.has(ARRAY_SYMBOL);
788
799
  };
789
800
  StateSpecNode.prototype.getSpec = function () {
790
- return this.specs[0];
801
+ return this._specs[0];
791
802
  };
792
803
  StateSpecNode.prototype.getAllSpecs = function () {
793
- return this.specs;
804
+ return this._specs;
794
805
  };
795
806
  StateSpecNode.prototype.getState = function (path) {
796
- return this.state[JSON.stringify(path)];
807
+ return this._state[JSON.stringify(path)];
808
+ };
809
+ StateSpecNode.prototype.getInitFunc = function (stateCell) {
810
+ var _a;
811
+ return (_a = stateCell.registeredInitFunc) !== null && _a !== void 0 ? _a : this.getSpec().initFunc;
797
812
  };
798
813
  StateSpecNode.prototype.clearStates = function () {
799
- this.state = {};
814
+ this._state = {};
800
815
  };
801
816
  StateSpecNode.prototype.states = function () {
802
- return Object.values(this.state);
817
+ return Object.values(this._state);
803
818
  };
804
819
  StateSpecNode.prototype.hasState = function (path) {
805
820
  var key = JSON.stringify(path);
806
- return key in this.state;
821
+ return key in this._state;
807
822
  };
808
823
  StateSpecNode.prototype.createStateCell = function (path) {
809
824
  var key = JSON.stringify(path);
810
- this.state[key] = {
825
+ this._state[key] = {
811
826
  listeners: [],
812
827
  initialValue: UNINITIALIZED,
813
- registeredInitFunc: this.getSpec().initFunc,
814
828
  path: path
815
829
  };
816
830
  };
817
831
  StateSpecNode.prototype.setInitialValue = function (path, value) {
818
832
  var key = JSON.stringify(path);
819
- this.state[key].initialValue = value;
833
+ this._state[key].initialValue = value;
820
834
  };
821
835
  StateSpecNode.prototype.getInitialValue = function (path) {
822
836
  var key = JSON.stringify(path);
823
- return this.state[key].initialValue;
837
+ return this._state[key].initialValue;
824
838
  };
825
839
  StateSpecNode.prototype.addListener = function (path, f) {
826
840
  var key = JSON.stringify(path);
827
- this.state[key].listeners.push(f);
841
+ this._state[key].listeners.push(f);
828
842
  };
829
843
  return StateSpecNode;
830
844
  }());
@@ -855,7 +869,31 @@ function buildTree(specs) {
855
869
  };
856
870
  return rec([]);
857
871
  }
858
- function getLeaves(root) {
872
+ function updateTree(root, specs) {
873
+ var internalSpec = specs.map(function (spec) {
874
+ return (__assign(__assign({}, spec), { pathObj: transformPathStringToObj(spec.path), isRepeated: spec.path.split(".").some(function (part) { return part.endsWith("[]"); }) }));
875
+ });
876
+ var rec = function (oldNode, currentPath) {
877
+ var nodeSpecs = internalSpec.filter(function (spec) {
878
+ return shallowEqual(currentPath, spec.pathObj.slice(0, currentPath.length));
879
+ });
880
+ var node = oldNode !== null && oldNode !== void 0 ? oldNode : new StateSpecNode(nodeSpecs);
881
+ node.setSpecs(nodeSpecs);
882
+ var oldEdges = oldNode === null || oldNode === void 0 ? void 0 : oldNode.edges();
883
+ node.clearEdges();
884
+ node.getAllSpecs().forEach(function (spec) {
885
+ if (spec.pathObj.length > currentPath.length) {
886
+ var nextKey = spec.pathObj[currentPath.length];
887
+ if (!node.hasEdge(nextKey)) {
888
+ node.addEdge(nextKey, rec(oldEdges === null || oldEdges === void 0 ? void 0 : oldEdges.get(nextKey), __spreadArray(__spreadArray([], __read(currentPath), false), [nextKey], false)));
889
+ }
890
+ }
891
+ });
892
+ return node;
893
+ };
894
+ return rec(root, []);
895
+ }
896
+ function getStateCells(root) {
859
897
  var leaves = [];
860
898
  var rec = function (node) {
861
899
  var e_1, _a;
@@ -872,7 +910,7 @@ function getLeaves(root) {
872
910
  }
873
911
  finally { if (e_1) throw e_1.error; }
874
912
  }
875
- if (node.isLeaf()) {
913
+ if (node.isLeaf() && node.getAllSpecs().length > 0) {
876
914
  leaves.push(node);
877
915
  }
878
916
  };
@@ -891,7 +929,6 @@ function findStateCell(root, pathStr, repetitionIndex) {
891
929
  if (!root.hasArrayTransition() ||
892
930
  !repetitionIndex ||
893
931
  currRepIndex > repetitionIndex.length) {
894
- console.log(root);
895
932
  throw new Error("transition not found: pathStr ".concat(pathStr, " part ").concat(typeof part === "symbol" ? "[]" : part));
896
933
  }
897
934
  realPath.push(repetitionIndex[currRepIndex++]);
@@ -951,8 +988,7 @@ function initializeStateValue($$state, initialSpecNode, initialStatePath, proxyR
951
988
  set(proxyRoot, initialStatePath, newValue);
952
989
  });
953
990
  });
954
- var initialValue = initialSpecNode.getState(initialStatePath)
955
- .registeredInitFunc($$state.props, $state, $$state.ctx);
991
+ var initialValue = initialSpecNode.getInitFunc(initialSpecNode.getState(initialStatePath))($$state.props, $state, $$state.ctx);
956
992
  initialSpecNode.setInitialValue(initialStatePath, clone(initialValue));
957
993
  var initialSpec = initialSpecNode.getSpec();
958
994
  var value = initialSpec.isImmutable
@@ -966,7 +1002,8 @@ function initializeStateValue($$state, initialSpecNode, initialStatePath, proxyR
966
1002
  return initialValue;
967
1003
  }
968
1004
  function create$StateProxy($$state, leafHandlers) {
969
- var rec = function (currPath, currNode, isOutside, proxyRoot, initialObject) {
1005
+ var proxyRoot;
1006
+ var rec = function (currPath, currNode, isOutside, initialObject) {
970
1007
  var getNextPath = function (property) { return __spreadArray(__spreadArray([], __read(currPath), false), [
971
1008
  isNum(property) ? +property : property,
972
1009
  ], false); };
@@ -985,7 +1022,7 @@ function create$StateProxy($$state, leafHandlers) {
985
1022
  //we are always in a leaf, since we only have two cases:
986
1023
  // 1 - delete properties outside the state tree
987
1024
  // 2 - delete indices in repeated implicit states, but these can't be exposed, so they don't have onChangeProp
988
- (_b = (_a = $$state.props)[spec.onChangeProp]) === null || _b === void 0 ? void 0 : _b.call(_a, get($$state.stateValues, currPath.slice(spec.pathObj.length)));
1025
+ (_b = (_a = $$state.props)[spec.onChangeProp]) === null || _b === void 0 ? void 0 : _b.call(_a, get(proxyRoot, currPath.slice(spec.pathObj.length)));
989
1026
  }
990
1027
  return Reflect.deleteProperty(target, property);
991
1028
  },
@@ -994,23 +1031,21 @@ function create$StateProxy($$state, leafHandlers) {
994
1031
  if (property === PLASMIC_STATE_PROXY_SYMBOL) {
995
1032
  return true;
996
1033
  }
997
- proxyRoot = proxyRoot == null ? receiver : proxyRoot;
998
1034
  var nextPath = getNextPath(property);
999
1035
  if (isOutside || currNode.isLeaf()) {
1000
1036
  return Reflect.get(target, property, receiver);
1001
1037
  }
1002
1038
  var nextNode = currNode.makeTransition(property);
1003
1039
  if (nextNode === null || nextNode === void 0 ? void 0 : nextNode.isLeaf()) {
1004
- return (_b = (_a = leafHandlers(nextNode, nextPath, proxyRoot)).get) === null || _b === void 0 ? void 0 : _b.call(_a, target, property, receiver);
1040
+ return (_b = (_a = leafHandlers(nextNode, nextPath)).get) === null || _b === void 0 ? void 0 : _b.call(_a, target, property, receiver);
1005
1041
  }
1006
1042
  else if (nextNode && !(property in target)) {
1007
- target[property] = rec(nextPath, nextNode, false, proxyRoot, undefined);
1043
+ target[property] = rec(nextPath, nextNode, false, undefined);
1008
1044
  }
1009
1045
  return Reflect.get(target, property, receiver);
1010
1046
  },
1011
1047
  set: function (target, property, value, receiver) {
1012
1048
  var _a, _b;
1013
- proxyRoot = proxyRoot == null ? receiver : proxyRoot;
1014
1049
  var nextPath = getNextPath(property);
1015
1050
  var nextNode = currNode.makeTransition(property);
1016
1051
  if (property === "registerInitFunc" && currPath.length === 0) {
@@ -1022,7 +1057,7 @@ function create$StateProxy($$state, leafHandlers) {
1022
1057
  return Reflect.set(target, property, value, receiver);
1023
1058
  }
1024
1059
  if (nextNode === null || nextNode === void 0 ? void 0 : nextNode.isLeaf()) {
1025
- (_b = (_a = leafHandlers(nextNode, nextPath, proxyRoot)).set) === null || _b === void 0 ? void 0 : _b.call(_a, target, property, value, receiver);
1060
+ (_b = (_a = leafHandlers(nextNode, nextPath)).set) === null || _b === void 0 ? void 0 : _b.call(_a, target, property, value, receiver);
1026
1061
  }
1027
1062
  if (!isOutside && !currNode.isLeaf() && !nextNode) {
1028
1063
  // can't set an unknown field in $state
@@ -1034,7 +1069,7 @@ function create$StateProxy($$state, leafHandlers) {
1034
1069
  nextNode = currNode;
1035
1070
  }
1036
1071
  if (canProxy(value)) {
1037
- target[property] = rec(nextPath, nextNode, isOutside || currNode.isLeaf(), proxyRoot, value);
1072
+ target[property] = rec(nextPath, nextNode, isOutside || currNode.isLeaf(), value);
1038
1073
  }
1039
1074
  else if (!isOutside && !currNode.isLeaf() && !(nextNode === null || nextNode === void 0 ? void 0 : nextNode.isLeaf())) {
1040
1075
  throw new Error("inserting a primitive value into a non-leaf");
@@ -1063,6 +1098,9 @@ function create$StateProxy($$state, leafHandlers) {
1063
1098
  ? []
1064
1099
  : Object.create(Object.getPrototypeOf(initialObject !== null && initialObject !== void 0 ? initialObject : {}));
1065
1100
  var proxyObj = new Proxy(baseObject, handlers);
1101
+ if (currPath.length === 0) {
1102
+ proxyRoot = proxyObj;
1103
+ }
1066
1104
  if (initialObject) {
1067
1105
  Reflect.ownKeys(initialObject).forEach(function (key) {
1068
1106
  var desc = Object.getOwnPropertyDescriptor(initialObject, key);
@@ -1076,67 +1114,100 @@ function create$StateProxy($$state, leafHandlers) {
1076
1114
  }
1077
1115
  return proxyObj;
1078
1116
  };
1079
- return rec([], $$state.rootSpecTree, false, undefined, undefined);
1117
+ return rec([], $$state.rootSpecTree, false, undefined);
1080
1118
  }
1081
1119
  var mkUntrackedValue = function (o) {
1082
1120
  return o != null && typeof o === "object" ? ref(o) : o;
1083
1121
  };
1084
- function useDollarState(specs, props, $ctx) {
1122
+ function useDollarState(specs, props, $ctx, opts) {
1085
1123
  var $$state = React__default.useRef((function () {
1086
1124
  var rootSpecTree = buildTree(specs);
1087
1125
  return {
1088
1126
  rootSpecTree: rootSpecTree,
1089
- specTreeLeaves: getLeaves(rootSpecTree),
1127
+ specTreeLeaves: getStateCells(rootSpecTree),
1090
1128
  stateValues: proxy({}),
1091
1129
  props: {},
1092
1130
  ctx: {},
1093
- registrationsQueue: []
1131
+ specs: [],
1132
+ registrationsQueue: proxy([])
1094
1133
  };
1095
1134
  })()).current;
1096
1135
  $$state.props = props;
1097
1136
  $$state.ctx = $ctx !== null && $ctx !== void 0 ? $ctx : {};
1098
- var $state = React__default.useRef(Object.assign(create$StateProxy($$state, function (node, path, proxyRoot) {
1099
- if (!node.hasState(path)) {
1100
- node.createStateCell(path);
1101
- var spec = node.getSpec();
1102
- if (spec.initFunc) {
1103
- initializeStateValue($$state, node, path, proxyRoot);
1104
- }
1105
- else if (!spec.valueProp) {
1106
- set(proxyRoot, path, spec.initVal);
1107
- }
1108
- }
1109
- return {
1110
- get: function (target, property, receiver) {
1137
+ $$state.specs = specs;
1138
+ var create$State = function () {
1139
+ var $state = Object.assign(create$StateProxy($$state, function (node, path) {
1140
+ if (!node.hasState(path)) {
1141
+ node.createStateCell(path);
1111
1142
  var spec = node.getSpec();
1112
- if (spec.valueProp) {
1113
- return $$state.props[spec.valueProp];
1143
+ if (spec.initFunc) {
1144
+ initializeStateValue($$state, node, path, $state);
1114
1145
  }
1115
- else {
1116
- return Reflect.get(target, property, receiver);
1146
+ else if (!spec.valueProp) {
1147
+ set($state, path, spec.initVal);
1117
1148
  }
1118
1149
  }
1119
- };
1120
- }), {
1121
- registerInitFunc: function (pathStr, f, repetitionIndex) {
1122
- var _a = findStateCell($$state.rootSpecTree, pathStr, repetitionIndex), node = _a.node, realPath = _a.realPath;
1123
- if (!node.hasState(realPath)) {
1124
- node.createStateCell(realPath);
1125
- }
1126
- if (!deepEqual(node.getState(realPath).initialValue, f($$state.props, $state, $$state.ctx))) {
1127
- $$state.registrationsQueue.push({ node: node, path: realPath, f: f });
1150
+ return {
1151
+ get: function (target, property, receiver) {
1152
+ var spec = node.getSpec();
1153
+ if (spec.valueProp) {
1154
+ return $$state.props[spec.valueProp];
1155
+ }
1156
+ else {
1157
+ return Reflect.get(target, property, receiver);
1158
+ }
1159
+ }
1160
+ };
1161
+ }), {
1162
+ registerInitFunc: function (pathStr, f, repetitionIndex) {
1163
+ var _a = findStateCell($$state.rootSpecTree, pathStr, repetitionIndex), node = _a.node, realPath = _a.realPath;
1164
+ if (!node.hasState(realPath)) {
1165
+ node.createStateCell(realPath);
1166
+ }
1167
+ if (!deepEqual(node.getState(realPath).initialValue, f($$state.props, $state, $$state.ctx))) {
1168
+ $$state.registrationsQueue.push(mkUntrackedValue({ node: node, path: realPath, f: f }));
1169
+ }
1128
1170
  }
1171
+ });
1172
+ return $state;
1173
+ };
1174
+ var ref = React__default.useRef(undefined);
1175
+ if (!ref.current) {
1176
+ ref.current = create$State();
1177
+ }
1178
+ var $state = ref.current;
1179
+ if (opts === null || opts === void 0 ? void 0 : opts.inCanvas) {
1180
+ $$state.rootSpecTree = updateTree($$state.rootSpecTree, specs);
1181
+ var newLeaves = getStateCells($$state.rootSpecTree);
1182
+ if (!arrayEq(newLeaves, $$state.specTreeLeaves)) {
1183
+ $state = ref.current = create$State();
1184
+ $$state.specTreeLeaves = newLeaves;
1129
1185
  }
1130
- })).current;
1186
+ // we need to eager initialize all states in canvas to populate the data picker
1187
+ $$state.specTreeLeaves.forEach(function (node) {
1188
+ var spec = node.getSpec();
1189
+ if (spec.isRepeated || node.hasState(spec.pathObj)) {
1190
+ return;
1191
+ }
1192
+ node.createStateCell(spec.pathObj);
1193
+ var init = spec.valueProp
1194
+ ? $$state.props[spec.valueProp]
1195
+ : spec.initFunc
1196
+ ? initializeStateValue($$state, node, spec.pathObj, $state)
1197
+ : spec.initVal;
1198
+ set($state, spec.pathObj, init);
1199
+ });
1200
+ }
1131
1201
  // For each spec with an initFunc, evaluate it and see if
1132
1202
  // the init value has changed. If so, reset its state.
1133
1203
  var resetSpecs = [];
1134
1204
  $$state.specTreeLeaves
1135
1205
  .flatMap(function (node) { return node.states().map(function (stateCell) { return ({ stateCell: stateCell, node: node }); }); })
1136
1206
  .forEach(function (_a) {
1137
- var stateCell = _a.stateCell, node = _a.node;
1138
- if (stateCell.registeredInitFunc) {
1139
- var newInit = stateCell.registeredInitFunc(props, $state, $ctx !== null && $ctx !== void 0 ? $ctx : {});
1207
+ var node = _a.node, stateCell = _a.stateCell;
1208
+ var initFunc = node.getInitFunc(stateCell);
1209
+ if (initFunc) {
1210
+ var newInit = initFunc(props, $state, $ctx !== null && $ctx !== void 0 ? $ctx : {});
1140
1211
  if (!deepEqual(newInit, stateCell.initialValue)) {
1141
1212
  resetSpecs.push({ stateCell: stateCell, node: node });
1142
1213
  }
@@ -1157,14 +1228,13 @@ function useDollarState(specs, props, $ctx) {
1157
1228
  });
1158
1229
  }, [props, resetSpecs]);
1159
1230
  useIsomorphicLayoutEffect(function () {
1160
- $$state.registrationsQueue.forEach(function (_a) {
1161
- var node = _a.node, path = _a.path, f = _a.f;
1231
+ while ($$state.registrationsQueue.length) {
1232
+ var _a = $$state.registrationsQueue.shift(), node = _a.node, path = _a.path, f = _a.f;
1162
1233
  var stateCell = node.getState(path);
1163
1234
  stateCell.registeredInitFunc = f;
1164
1235
  reInitializeState(node, stateCell);
1165
- });
1166
- $$state.registrationsQueue = [];
1167
- }, [$$state.registrationsQueue]);
1236
+ }
1237
+ }, [$$state.registrationsQueue.length]);
1168
1238
  // immediately initialize exposed non-private states
1169
1239
  useIsomorphicLayoutEffect(function () {
1170
1240
  $$state.specTreeLeaves.forEach(function (node) {
@@ -1177,6 +1247,7 @@ function useDollarState(specs, props, $ctx) {
1177
1247
  }, []);
1178
1248
  // Re-render if any value changed in one of these objects
1179
1249
  useSnapshot($$state.stateValues, { sync: true });
1250
+ useSnapshot($$state.registrationsQueue);
1180
1251
  return $state;
1181
1252
  }
1182
1253