@plasmicapp/react-web 0.2.102 → 0.2.103

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.
@@ -25,7 +25,7 @@ var listbox = require('@react-aria/listbox');
25
25
  var select$1 = require('@react-stately/select');
26
26
  var _switch = require('@react-aria/switch');
27
27
  var overlays = require('@react-aria/overlays');
28
- var get = _interopDefault(require('dlv'));
28
+ var _get = _interopDefault(require('dlv'));
29
29
  var dset = require('dset');
30
30
 
31
31
  function _extends() {
@@ -1206,6 +1206,96 @@ function isInternalHref(href) {
1206
1206
  return /^\/(?!\/)/.test(href);
1207
1207
  }
1208
1208
 
1209
+ var PlasmicTranslatorContext = /*#__PURE__*/React__default.createContext(undefined);
1210
+
1211
+ function isIterable(val) {
1212
+ return val != null && typeof val[Symbol.iterator] === "function";
1213
+ }
1214
+
1215
+ function genTranslatableString(elt) {
1216
+ var components = {};
1217
+ var componentsCount = 0;
1218
+
1219
+ var getText = function getText(node) {
1220
+ if (!node) {
1221
+ return "";
1222
+ }
1223
+
1224
+ if (typeof node === "number" || typeof node === "boolean" || typeof node === "string") {
1225
+ return node.toString();
1226
+ }
1227
+
1228
+ if (typeof node !== "object") {
1229
+ return "";
1230
+ }
1231
+
1232
+ if (Array.isArray(node) || isIterable(node)) {
1233
+ return Array.from(node).map(function (child) {
1234
+ return getText(child);
1235
+ }).filter(function (child) {
1236
+ return !!child;
1237
+ }).join("");
1238
+ }
1239
+
1240
+ var nodeChildren = hasKey(node, "props") && hasKey(node.props, "children") && node.props.children || hasKey(node, "children") && node.children || [];
1241
+ var contents = "" + React__default.Children.toArray(nodeChildren).map(function (child) {
1242
+ return getText(child);
1243
+ }).filter(function (child) {
1244
+ return !!child;
1245
+ }).join("");
1246
+
1247
+ if (React__default.isValidElement(node) && node.type === React__default.Fragment) {
1248
+ return contents;
1249
+ }
1250
+
1251
+ var componentId = componentsCount + 1;
1252
+ componentsCount++;
1253
+ components[componentId] = React__default.isValidElement(node) ? React__default.cloneElement(node, {
1254
+ key: componentId,
1255
+ children: undefined
1256
+ }) : node;
1257
+ return "<" + componentId + ">" + contents + "</" + componentId + ">";
1258
+ };
1259
+
1260
+ var str = getText(elt);
1261
+ return {
1262
+ str: str,
1263
+ components: components,
1264
+ componentsCount: componentsCount
1265
+ };
1266
+ }
1267
+ function Trans(_ref) {
1268
+ var children = _ref.children;
1269
+
1270
+ var _t = React__default.useContext(PlasmicTranslatorContext);
1271
+
1272
+ if (!_t) {
1273
+ warnNoTranslationFunctionAtMostOnce();
1274
+ return children;
1275
+ }
1276
+
1277
+ var _genTranslatableStrin = genTranslatableString(children),
1278
+ str = _genTranslatableStrin.str,
1279
+ components = _genTranslatableStrin.components,
1280
+ componentsCount = _genTranslatableStrin.componentsCount;
1281
+
1282
+ return _t(str, componentsCount > 0 ? {
1283
+ components: components
1284
+ } : undefined);
1285
+ }
1286
+ var hasWarned = false;
1287
+
1288
+ function warnNoTranslationFunctionAtMostOnce() {
1289
+ if (!hasWarned) {
1290
+ console.warn("Using Plasmic Translation but no translation function has been provided");
1291
+ hasWarned = true;
1292
+ }
1293
+ }
1294
+
1295
+ function hasKey(v, key) {
1296
+ return typeof v === "object" && v !== null && key in v;
1297
+ }
1298
+
1209
1299
  function PlasmicSlot(props) {
1210
1300
  return renderPlasmicSlot(props);
1211
1301
  }
@@ -1249,7 +1339,8 @@ function renderPlasmicSlot(opts) {
1249
1339
 
1250
1340
  function maybeAsString(node) {
1251
1341
  // Unwrap fragments
1252
- if (React.isValidElement(node) && node.type === React.Fragment) {
1342
+ if (React.isValidElement(node) && ( // Fragment and Trans don't render DOM elements
1343
+ node.type === React.Fragment || node.type === Trans)) {
1253
1344
  return maybeAsString(node.props.children);
1254
1345
  }
1255
1346
 
@@ -1360,96 +1451,6 @@ function createUseScreenVariants(isMulti, screenQueries) {
1360
1451
  };
1361
1452
  }
1362
1453
 
1363
- var PlasmicTranslatorContext = /*#__PURE__*/React__default.createContext(undefined);
1364
-
1365
- function isIterable(val) {
1366
- return val != null && typeof val[Symbol.iterator] === "function";
1367
- }
1368
-
1369
- function genTranslatableString(elt) {
1370
- var components = {};
1371
- var componentsCount = 0;
1372
-
1373
- var getText = function getText(node) {
1374
- if (!node) {
1375
- return "";
1376
- }
1377
-
1378
- if (typeof node === "number" || typeof node === "boolean" || typeof node === "string") {
1379
- return node.toString();
1380
- }
1381
-
1382
- if (typeof node !== "object") {
1383
- return "";
1384
- }
1385
-
1386
- if (Array.isArray(node) || isIterable(node)) {
1387
- return Array.from(node).map(function (child) {
1388
- return getText(child);
1389
- }).filter(function (child) {
1390
- return !!child;
1391
- }).join("");
1392
- }
1393
-
1394
- var nodeChildren = hasKey(node, "props") && hasKey(node.props, "children") && node.props.children || hasKey(node, "children") && node.children || [];
1395
- var contents = "" + React__default.Children.toArray(nodeChildren).map(function (child) {
1396
- return getText(child);
1397
- }).filter(function (child) {
1398
- return !!child;
1399
- }).join("");
1400
-
1401
- if (React__default.isValidElement(node) && node.type === React__default.Fragment) {
1402
- return contents;
1403
- }
1404
-
1405
- var componentId = componentsCount + 1;
1406
- componentsCount++;
1407
- components[componentId] = React__default.isValidElement(node) ? React__default.cloneElement(node, {
1408
- key: componentId,
1409
- children: undefined
1410
- }) : node;
1411
- return "<" + componentId + ">" + contents + "</" + componentId + ">";
1412
- };
1413
-
1414
- var str = getText(elt);
1415
- return {
1416
- str: str,
1417
- components: components,
1418
- componentsCount: componentsCount
1419
- };
1420
- }
1421
- function Trans(_ref) {
1422
- var children = _ref.children;
1423
-
1424
- var _t = React__default.useContext(PlasmicTranslatorContext);
1425
-
1426
- if (!_t) {
1427
- warnNoTranslationFunctionAtMostOnce();
1428
- return children;
1429
- }
1430
-
1431
- var _genTranslatableStrin = genTranslatableString(children),
1432
- str = _genTranslatableStrin.str,
1433
- components = _genTranslatableStrin.components,
1434
- componentsCount = _genTranslatableStrin.componentsCount;
1435
-
1436
- return _t(str, componentsCount > 0 ? {
1437
- components: components
1438
- } : undefined);
1439
- }
1440
- var hasWarned = false;
1441
-
1442
- function warnNoTranslationFunctionAtMostOnce() {
1443
- if (!hasWarned) {
1444
- console.warn("Using Plasmic Translation but no translation function has been provided");
1445
- hasWarned = true;
1446
- }
1447
- }
1448
-
1449
- function hasKey(v, key) {
1450
- return typeof v === "object" && v !== null && key in v;
1451
- }
1452
-
1453
1454
  var PlasmicRootContext = /*#__PURE__*/React.createContext(undefined);
1454
1455
  function PlasmicRootProvider(props) {
1455
1456
  var platform = props.platform,
@@ -3124,40 +3125,24 @@ function useTriggeredOverlay(plasmicClass, props, config, outerRef) {
3124
3125
  };
3125
3126
  }
3126
3127
 
3127
- var UNINITIALIZED = /*#__PURE__*/Symbol("plasmic.unitialized");
3128
- function keyBy(list, keyFunc) {
3129
- var keyedObject = {};
3130
-
3131
- for (var _iterator = _createForOfIteratorHelperLoose(list), _step; !(_step = _iterator()).done;) {
3132
- var val = _step.value;
3133
- keyedObject[keyFunc(val)] = val;
3134
- }
3135
-
3136
- return keyedObject;
3128
+ function generateStateOnChangeProp($state, stateName, dataReps) {
3129
+ return function (val, path) {
3130
+ return dset.dset($state, [stateName].concat(dataReps, path), val);
3131
+ };
3137
3132
  }
3133
+ /**
3134
+ * This function generate the state value prop for repeated states
3135
+ * Example:
3136
+ * - parent[][].counter[].count
3137
+ * We need to pass `parent[index1][index2].counter to the child component
3138
+ */
3138
3139
 
3139
- function getObjectAtPath($state, path) {
3140
- var parts = path.split(".");
3141
- var parts2 = parts.slice(0, parts.length - 1);
3142
-
3143
- if (parts2.length === 0) {
3144
- return $state;
3145
- }
3146
-
3147
- var existing = get($state, parts2);
3148
-
3149
- if (existing) {
3150
- return existing;
3151
- }
3152
-
3153
- var newObj = {};
3154
- dset.dset($state, parts2, newObj);
3155
- return newObj;
3140
+ function generateStateValueProp($state, path // ["parent", 0, 1, "counter"]
3141
+ ) {
3142
+ return _get($state, path);
3156
3143
  }
3157
3144
 
3158
- function isRendering() {
3159
- return !!React__default.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner.current;
3160
- }
3145
+ var UNINITIALIZED = /*#__PURE__*/Symbol("plasmic.unitialized");
3161
3146
 
3162
3147
  function shallowEqual(a1, a2) {
3163
3148
  if (a1.length !== a2.length) {
@@ -3173,289 +3158,349 @@ function shallowEqual(a1, a2) {
3173
3158
  return true;
3174
3159
  }
3175
3160
 
3176
- function useVanillaDollarState(specs, props) {
3177
- var _React$useState = React__default.useState(function () {
3161
+ var isNum = function isNum(value) {
3162
+ return typeof value === "symbol" ? false : !isNaN(+value);
3163
+ };
3164
+
3165
+ function mkProxy(specs, maybeHandlers) {
3166
+ var handlers = maybeHandlers != null ? maybeHandlers : function () {
3178
3167
  return {
3179
- stateValues: Object.fromEntries(specs.map(function (spec) {
3180
- return [spec.path, // If the initial value depends on initFunc, then we initialize
3181
- // it to this special UNINITIALIZED symbol. We can't just run
3182
- // spec.initFunc() here, because the expression may read from
3183
- // $state, which is not yet initialized. Instead, we will
3184
- // lazily compute and initialize this at get() time.
3185
- spec.initFunc ? UNINITIALIZED : spec.initVal];
3186
- })),
3187
- initStateValues: Object.fromEntries(specs.filter(function (spec) {
3188
- return !spec.initFunc;
3189
- }).map(function (spec) {
3190
- return [spec.path, spec.initVal];
3191
- })),
3192
- initStateDeps: {},
3193
- fireOnChange: {}
3168
+ get: function get(target, property) {
3169
+ return target[property];
3170
+ },
3171
+ set: function set(target, property, value) {
3172
+ return (target[property] = value) || true;
3173
+ }
3194
3174
  };
3195
- }),
3196
- _$$state = _React$useState[0],
3197
- set$$State = _React$useState[1]; // We have a weird scheme here to reduce the number of state updates.
3198
- // Whenever user does a $state get() or set(), we may end up initializing
3199
- // a bunch of values. We don't want to call set$$State() a bunch of times.
3200
- // Instead, we will fork as we need to, and call set$$State() at the end of
3201
- // the hook and at the end of get() / set() as appropriate.
3202
- // $$state here is going to be copied-on-write; once copied, it will
3203
- // be directly mutated. Since $state will always be directly proxying $$state,
3204
- // that means you can "read what you wrote": after $state.count = $state.count + 1,
3205
- // if you read $state.count again, it will reflect the latest value.
3206
- //
3207
- // There are three places where we might actually call set$$State():
3208
- // 1. At the end of a "top-level" get(): we may have ended up initializing
3209
- // some state values.
3210
- // 2. At the end of a "top-level" set(): we mutated this value, but also
3211
- // may have reset some other state values that depended on this one.
3212
- // 3. At the end of the hook, where we compare the new initial value with
3213
- // the previous initial value.
3214
-
3215
-
3216
- var $$state = _extends({}, _$$state);
3217
-
3218
- var dirtyFields = {
3219
- stateValues: false,
3220
- initStateValues: false,
3221
- initStateDeps: false,
3222
- fireOnChange: false
3223
3175
  };
3224
3176
 
3225
- function makeDirty(field, copy) {
3226
- if (!dirtyFields[field]) {
3227
- dirtyFields[field] = true;
3228
- $$state[field] = copy($$state[field]);
3229
- }
3230
- }
3177
+ var rec = function rec(currPath) {
3178
+ var nextParts = Object.fromEntries(specs.filter(function (spec) {
3179
+ return shallowEqual(currPath.map(function (p) {
3180
+ return isNum(p) ? "[]" : p;
3181
+ }), spec.path.slice(0, currPath.length));
3182
+ }).map(function (spec) {
3183
+ var nextPart = spec.path[currPath.length];
3184
+
3185
+ if (spec.path.length === currPath.length + 1) {
3186
+ return [nextPart, {
3187
+ isLast: true,
3188
+ spec: spec
3189
+ }];
3190
+ } else {
3191
+ return [nextPart, {
3192
+ isLast: false,
3193
+ spec: spec
3194
+ }];
3195
+ }
3196
+ }));
3197
+ return new Proxy("[]" in nextParts ? [] : {}, {
3198
+ get: function get(target, property, receiver) {
3199
+ if ("[]" in nextParts && isNum(property)) {
3200
+ if (!(property in target)) {
3201
+ target[property] = rec([].concat(currPath, [+property]));
3202
+ }
3203
+ } else if (property in nextParts) {
3204
+ if (nextParts[property].isLast) {
3205
+ var _handlers$get, _handlers;
3206
+
3207
+ return handlers == null ? void 0 : (_handlers$get = (_handlers = handlers({
3208
+ path: [].concat(currPath, [property]),
3209
+ spec: nextParts[property].spec
3210
+ })).get) == null ? void 0 : _handlers$get.call(_handlers, target, property, receiver);
3211
+ } else if (!(property in target)) {
3212
+ target[property] = rec([].concat(currPath, [property]));
3213
+ }
3214
+ }
3231
3215
 
3232
- function updateStateValue(path, value) {
3233
- makeDirty("stateValues", function (x) {
3234
- return _extends({}, x);
3216
+ return target[property];
3217
+ },
3218
+ set: function set(target, property, value, receiver) {
3219
+ if (!(property in target) && property in nextParts) {
3220
+ if (nextParts[property].isLast) {
3221
+ var _handlers$set, _handlers$set2, _handlers2;
3222
+
3223
+ return (_handlers$set = (_handlers$set2 = (_handlers2 = handlers({
3224
+ path: [].concat(currPath, [property]),
3225
+ spec: nextParts[property].spec
3226
+ })).set) == null ? void 0 : _handlers$set2.call(_handlers2, target, property, value, receiver)) != null ? _handlers$set : false;
3227
+ } else {
3228
+ throw new Error("You can't set a value in the middle of the path");
3229
+ }
3230
+ } else {
3231
+ target[property] = value;
3232
+ return true;
3233
+ }
3234
+ }
3235
3235
  });
3236
- console.log("UPDATE state value:", path, value);
3237
- $$state.stateValues[path] = value; // If any other state depends on this one, then reset their
3238
- // values to their initial as well
3239
-
3240
- for (var _i = 0, _Object$entries = Object.entries($$state.initStateDeps); _i < _Object$entries.length; _i++) {
3241
- var _Object$entries$_i = _Object$entries[_i],
3242
- key = _Object$entries$_i[0],
3243
- deps = _Object$entries$_i[1];
3236
+ };
3244
3237
 
3245
- if (deps.includes(path)) {
3246
- resetPath(key);
3247
- }
3248
- }
3238
+ return rec([]);
3239
+ }
3249
3240
 
3250
- var spec = specByPath[path];
3241
+ function cloneProxy(specs, states, obj) {
3242
+ var newObj = mkProxy(specs);
3243
+ Object.values(states).forEach(function (_ref) {
3244
+ var path = _ref.path;
3251
3245
 
3252
- if (spec.onChangeProp) {
3253
- if (isRendering()) {
3254
- // If we're currently rendering this component, then we
3255
- // CANNOT fire the event handler, as it is illegal to set
3256
- // the state of another component during rendering.
3257
- // Instead, we save it into our internal state, and fire
3258
- // it later in a layout effect.
3259
- updateFireOnChange(spec.path, value);
3260
- } else {
3261
- var _props$spec$onChangeP;
3246
+ dset.dset(newObj, path, _get(obj, path));
3247
+ });
3248
+ return newObj;
3249
+ }
3262
3250
 
3263
- // Most of the time, state changes outside of rendering
3264
- // (in an event handler), and we just directly call the
3265
- // onChange
3266
- (_props$spec$onChangeP = props[spec.onChangeProp]) == null ? void 0 : _props$spec$onChangeP.call(props, value);
3267
- }
3268
- }
3269
- }
3251
+ function saveState(state, states) {
3252
+ states[JSON.stringify(state.path)] = state;
3253
+ }
3270
3254
 
3271
- function updateInitStateValue(path, value) {
3272
- makeDirty("initStateValues", function (x) {
3273
- return _extends({}, x);
3274
- });
3275
- console.log("UPDATE initValue:", path, value);
3276
- $$state.initStateValues[path] = value;
3277
- }
3255
+ function hasState(state, states) {
3256
+ return JSON.stringify(state.path) in states;
3257
+ }
3278
3258
 
3279
- function updateInitStateDeps(path, deps) {
3280
- makeDirty("initStateDeps", function (x) {
3281
- return _extends({}, x);
3282
- });
3283
- console.log("UPDATE DEPS: " + path, deps);
3284
- $$state.initStateDeps[path] = deps;
3285
- }
3259
+ var transformPathStringToObj = function transformPathStringToObj(str) {
3260
+ // "c[][]" -> ["c", "[]", "[]"]
3261
+ var splitStatePathPart = function splitStatePathPart(state) {
3262
+ return state.endsWith("[]") ? [].concat(splitStatePathPart(state.slice(0, -2)), ["[]"]) : [state];
3263
+ };
3286
3264
 
3287
- function updateInternalStateIfDirty() {
3288
- if (Object.values(dirtyFields).some(function (x) {
3289
- return x;
3290
- })) {
3291
- console.log("UPDATE $$STATE");
3292
- set$$State($$state);
3293
- }
3294
- }
3265
+ return str.split(".").flatMap(splitStatePathPart);
3266
+ };
3295
3267
 
3296
- function updateFireOnChange(path, value) {
3297
- makeDirty("fireOnChange", function (x) {
3298
- return _extends({}, x);
3268
+ function useVanillaDollarState(_specs, props) {
3269
+ var specs = _specs.map(function (_ref2) {
3270
+ var pathStr = _ref2.path,
3271
+ spec = _objectWithoutPropertiesLoose(_ref2, ["path"]);
3272
+
3273
+ return _extends({}, spec, {
3274
+ pathStr: pathStr,
3275
+ path: transformPathStringToObj(pathStr),
3276
+ isRepeated: pathStr.split(".").some(function (part) {
3277
+ return part.endsWith("[]");
3278
+ })
3299
3279
  });
3300
- $$state.fireOnChange[path] = value;
3301
- }
3280
+ });
3302
3281
 
3303
- console.log("useDollarState", _extends({}, _$$state));
3304
- var specByPath = React__default.useMemo(function () {
3305
- return keyBy(specs, function (spec) {
3306
- return spec.path;
3307
- });
3308
- }, [specs]);
3309
- var stateAccessStack = [{}];
3310
- var $props = props;
3311
- /**
3312
- * Runs spec.initFunc, keeping track of the state accesses
3313
- * that occurred while running it
3314
- */
3315
-
3316
- function trackedInit(spec) {
3317
- var _$$state$initStateDep;
3318
-
3319
- var stateAccess = {};
3320
- stateAccessStack.push(stateAccess);
3321
- var res = spec.initFunc($props, $state);
3322
- var deps = Object.keys(stateAccess);
3323
-
3324
- if (!shallowEqual(deps, (_$$state$initStateDep = $$state.initStateDeps[spec.path]) != null ? _$$state$initStateDep : [])) {
3325
- updateInitStateDeps(spec.path, deps);
3326
- }
3282
+ var _React$useState = React__default.useState(function () {
3283
+ var stateValues = mkProxy(specs);
3284
+ var initStates = {};
3327
3285
 
3328
- stateAccessStack.pop();
3329
- return res;
3330
- }
3331
- /**
3332
- * Resets the value for this state
3333
- */
3286
+ for (var _iterator = _createForOfIteratorHelperLoose(specs), _step; !(_step = _iterator()).done;) {
3287
+ var spec = _step.value;
3334
3288
 
3289
+ if (spec.valueProp || spec.isRepeated) {
3290
+ continue;
3291
+ } else if (spec.initFunc) {
3292
+ dset.dset(stateValues, spec.path, UNINITIALIZED);
3293
+ } else {
3294
+ var _spec$initVal;
3335
3295
 
3336
- function resetPath(path) {
3337
- // Resets the value for this state
3338
- var spec = specByPath[path];
3339
- var initValue = trackedInit(spec);
3296
+ dset.dset(stateValues, spec.path, (_spec$initVal = spec.initVal) != null ? _spec$initVal : undefined);
3297
+ }
3340
3298
 
3341
- if (initValue !== $$state.stateValues[spec.path]) {
3342
- updateStateValue(spec.path, initValue);
3299
+ saveState({
3300
+ path: spec.path,
3301
+ spec: spec
3302
+ }, initStates);
3343
3303
  }
3344
3304
 
3345
- if (initValue !== $$state.initStateValues[spec.path]) {
3346
- updateInitStateValue(spec.path, initValue);
3347
- }
3305
+ var deps = fillUninitializedStateValues(specs, props, stateValues, initStates);
3306
+ return {
3307
+ stateValues: stateValues,
3308
+ initStateDeps: deps,
3309
+ initStateValues: cloneProxy(specs, initStates, stateValues),
3310
+ states: initStates
3311
+ };
3312
+ }),
3313
+ $$state = _React$useState[0],
3314
+ set$$State = _React$useState[1];
3348
3315
 
3349
- return initValue;
3350
- } // Since a get() or a set() may result in other get() or set(),
3351
- // we keep track of whether we're at the "top-level" so we know
3352
- // whether to update state at the end.
3316
+ var $state = mkProxy(specs, function (state) {
3317
+ return {
3318
+ get: function get(_target, _property) {
3319
+ if (state.spec.valueProp) {
3320
+ if (!state.spec.isRepeated) {
3321
+ return props[state.spec.valueProp];
3322
+ } else {
3323
+ return _get(props[state.spec.valueProp], state.path.slice(1));
3324
+ }
3325
+ }
3353
3326
 
3327
+ if (!hasState(state, $$state.states)) {
3328
+ var _state$spec$initVal;
3354
3329
 
3355
- var accessLevel = 0;
3356
- var $state = {};
3330
+ saveState(state, $$state.states);
3357
3331
 
3358
- var _loop = function _loop() {
3359
- var spec = _step2.value;
3360
- var parts = spec.path.split(".");
3361
- var name = parts[parts.length - 1];
3362
- var obj = getObjectAtPath($state, spec.path); // Define get() and set() for this state cell
3332
+ dset.dset($$state.stateValues, state.path, state.spec.initFunc ? UNINITIALIZED : (_state$spec$initVal = state.spec.initVal) != null ? _state$spec$initVal : undefined);
3363
3333
 
3364
- Object.defineProperty(obj, name, {
3365
- get: function get() {
3366
- if (spec.valueProp) {
3367
- return props[spec.valueProp];
3368
- }
3334
+ var deps = state.spec.initFunc ? fillUninitializedStateValues(specs, props, $$state.stateValues, $$state.states) : {};
3369
3335
 
3370
- accessLevel += 1;
3371
- var value = $$state.stateValues[spec.path];
3336
+ dset.dset($$state.initStateValues, state.path, _get($$state.stateValues, state.path));
3372
3337
 
3373
- if (value === UNINITIALIZED) {
3374
- // This value has a init expression; need to be evaluated.
3375
- value = resetPath(spec.path);
3376
- } // Record that this field had just been accessed; for
3377
- // trackInit() to know what fields were used to compute
3378
- // the init value
3338
+ set$$State(function (prev) {
3339
+ return {
3340
+ initStateValues: cloneProxy(specs, prev.states, prev.stateValues),
3341
+ stateValues: cloneProxy(specs, prev.states, prev.initStateValues),
3342
+ initStateDeps: _extends({}, prev.initStateDeps, deps),
3343
+ states: _extends({}, prev.states)
3344
+ };
3345
+ });
3346
+ }
3379
3347
 
3348
+ return _get($$state.stateValues, state.path);
3349
+ },
3350
+ set: function set(_target, _property, newValue) {
3351
+ saveState(state, $$state.states);
3380
3352
 
3381
- stateAccessStack[stateAccessStack.length - 1][spec.path] = true;
3382
- accessLevel -= 1;
3353
+ if (newValue !== _get($$state.stateValues, state.path)) {
3354
+ dset.dset($$state.stateValues, state.path, newValue);
3383
3355
 
3384
- if (accessLevel === 0) {
3385
- updateInternalStateIfDirty();
3386
- }
3356
+ for (var _i = 0, _Object$entries = Object.entries($$state.initStateDeps); _i < _Object$entries.length; _i++) {
3357
+ var _Object$entries$_i = _Object$entries[_i],
3358
+ key = _Object$entries$_i[0],
3359
+ deps = _Object$entries$_i[1];
3387
3360
 
3388
- return value;
3389
- },
3390
- set: function set(newValue) {
3391
- accessLevel += 1;
3361
+ if (deps.includes(JSON.stringify(state.path))) {
3362
+ dset.dset($$state.stateValues, JSON.parse(key), UNINITIALIZED);
3363
+ }
3364
+ }
3392
3365
 
3393
- if (newValue !== $$state.stateValues[spec.path]) {
3394
- updateStateValue(spec.path, newValue);
3395
- }
3366
+ var newDeps = fillUninitializedStateValues(specs, props, $$state.stateValues, $$state.states);
3367
+ set$$State(function (prev) {
3368
+ return {
3369
+ initStateValues: _extends({}, prev.initStateValues),
3370
+ stateValues: cloneProxy(specs, prev.states, prev.stateValues),
3371
+ initStateDeps: _extends({}, prev.initStateDeps, newDeps),
3372
+ states: _extends({}, prev.states)
3373
+ };
3374
+ });
3396
3375
 
3397
- accessLevel -= 1;
3376
+ if (state.spec.onChangeProp) {
3377
+ var _props$state$spec$onC;
3398
3378
 
3399
- if (accessLevel === 0) {
3400
- updateInternalStateIfDirty();
3379
+ (_props$state$spec$onC = props[state.spec.onChangeProp]) == null ? void 0 : _props$state$spec$onC.call(props, newValue, state.path);
3380
+ }
3401
3381
  }
3402
- }
3403
- });
3404
- };
3405
3382
 
3406
- for (var _iterator2 = _createForOfIteratorHelperLoose(specs), _step2; !(_step2 = _iterator2()).done;) {
3407
- _loop();
3408
- } // For each spec with an initFunc, evaluate it and see if
3383
+ return true;
3384
+ }
3385
+ };
3386
+ }); // For each spec with an initFunc, evaluate it and see if
3409
3387
  // the init value has changed. If so, reset its state.
3410
3388
 
3389
+ var newStateValues = undefined;
3390
+ var resetSpecs = [];
3411
3391
 
3412
- for (var _iterator3 = _createForOfIteratorHelperLoose(specs), _step3; !(_step3 = _iterator3()).done;) {
3413
- var spec = _step3.value;
3392
+ for (var _i2 = 0, _Object$values = Object.values($$state.states); _i2 < _Object$values.length; _i2++) {
3393
+ var _Object$values$_i = _Object$values[_i2],
3394
+ path = _Object$values$_i.path,
3395
+ spec = _Object$values$_i.spec;
3414
3396
 
3415
3397
  if (spec.initFunc) {
3416
- var newInit = spec.initFunc($props, $state);
3398
+ var newInit = spec.initFunc(props, $state);
3417
3399
 
3418
- if (newInit !== $$state.initStateValues[spec.path]) {
3419
- console.log("init changed for " + spec.path + " from " + $$state.initStateValues[spec.path] + " to " + newInit + "; resetting state");
3420
- updateInitStateValue(spec.path, newInit);
3421
- updateStateValue(spec.path, newInit);
3400
+ if (newInit !== _get($$state.initStateValues, path)) {
3401
+ console.log("init changed for " + JSON.stringify(path) + " from " + _get($$state.initStateValues, path) + " to " + newInit + "; resetting state");
3402
+ resetSpecs.push({
3403
+ path: path,
3404
+ spec: spec
3405
+ });
3422
3406
 
3423
- if (spec.onChangeProp) {
3424
- updateFireOnChange(spec.path, newInit);
3407
+ if (!newStateValues) {
3408
+ newStateValues = cloneProxy(specs, $$state.states, $$state.stateValues);
3425
3409
  }
3410
+
3411
+ dset.dset(newStateValues, path, UNINITIALIZED);
3426
3412
  }
3427
3413
  }
3428
3414
  }
3429
3415
 
3430
- var fireOnChange = $$state.fireOnChange;
3431
3416
  React__default.useLayoutEffect(function () {
3432
- if (Object.keys(fireOnChange).length > 0) {
3433
- for (var _i2 = 0, _Object$entries2 = Object.entries(fireOnChange); _i2 < _Object$entries2.length; _i2++) {
3434
- var _Object$entries2$_i = _Object$entries2[_i2],
3435
- path = _Object$entries2$_i[0],
3436
- value = _Object$entries2$_i[1];
3437
- var spec = specByPath[path];
3417
+ if (newStateValues !== undefined) {
3418
+ var newDeps = fillUninitializedStateValues(specs, props, newStateValues, $$state.states);
3419
+ set$$State(function (prev) {
3420
+ var initStateValues = cloneProxy(specs, prev.states, prev.initStateValues);
3421
+ resetSpecs.forEach(function (_ref3) {
3422
+ var path = _ref3.path;
3423
+
3424
+ dset.dset(initStateValues, path, _get(newStateValues, path));
3425
+ });
3426
+ return {
3427
+ stateValues: cloneProxy(specs, prev.states, newStateValues),
3428
+ initStateDeps: _extends({}, prev.initStateDeps, newDeps),
3429
+ initStateValues: initStateValues,
3430
+ states: _extends({}, prev.states)
3431
+ };
3432
+ });
3433
+
3434
+ for (var _iterator2 = _createForOfIteratorHelperLoose(resetSpecs), _step2; !(_step2 = _iterator2()).done;) {
3435
+ var _step2$value = _step2.value,
3436
+ _path = _step2$value.path,
3437
+ _spec = _step2$value.spec;
3438
3438
 
3439
- if (spec.onChangeProp) {
3440
- var _props$spec$onChangeP2;
3439
+ if (_spec.onChangeProp) {
3440
+ var _props$_spec$onChange;
3441
3441
 
3442
- (_props$spec$onChangeP2 = props[spec.onChangeProp]) == null ? void 0 : _props$spec$onChangeP2.call(props, value);
3442
+ console.log("Firing onChange for reset init value: " + _spec.path, _get(newStateValues, _path));
3443
+ (_props$_spec$onChange = props[_spec.onChangeProp]) == null ? void 0 : _props$_spec$onChange.call(props, _get(newStateValues, _path));
3443
3444
  }
3444
3445
  }
3445
-
3446
- set$$State(function (prev) {
3447
- return _extends({}, prev, {
3448
- fireOnChange: {}
3449
- });
3450
- });
3451
3446
  }
3452
- }, [fireOnChange, props, specByPath]); // update state if the above did some writes.
3453
-
3454
- updateInternalStateIfDirty();
3447
+ }, [newStateValues, props, resetSpecs, specs]);
3455
3448
  return $state;
3456
3449
  }
3457
3450
 
3458
- var useDollarState = useVanillaDollarState;
3451
+ function fillUninitializedStateValues(specs, props, stateValues, states) {
3452
+ var stateAccessStack = [new Set()];
3453
+ var initFuncDeps = {};
3454
+ var $state = mkProxy(specs, function (state) {
3455
+ return {
3456
+ get: function get(_target, _property) {
3457
+ if (state.spec.valueProp) {
3458
+ if (!state.spec.isRepeated) {
3459
+ return props[state.spec.valueProp];
3460
+ } else {
3461
+ return _get(props[state.spec.valueProp], state.path.slice(1));
3462
+ }
3463
+ }
3464
+
3465
+ var value = _get(stateValues, state.path);
3466
+
3467
+ if (value === UNINITIALIZED) {
3468
+ // This value has a init expression; need to be evaluated.
3469
+ value = tracked(state);
3470
+
3471
+ dset.dset(stateValues, state.path, value);
3472
+ } // Record that this field had just been accessed; for
3473
+ // trackInit() to know what fields were used to compute
3474
+ // the init value
3475
+
3476
+
3477
+ stateAccessStack[stateAccessStack.length - 1].add(JSON.stringify(state.path));
3478
+ return value;
3479
+ },
3480
+ set: function set() {
3481
+ throw new Error("Cannot update state values during initialization");
3482
+ }
3483
+ };
3484
+ });
3485
+
3486
+ function tracked(state) {
3487
+ stateAccessStack.push(new Set());
3488
+ var res = state.spec.initFunc(props, $state);
3489
+ var deps = stateAccessStack.pop();
3490
+ initFuncDeps[JSON.stringify(state.path)] = [].concat(deps.values());
3491
+ return res;
3492
+ }
3493
+
3494
+ for (var _i3 = 0, _Object$values2 = Object.values(states); _i3 < _Object$values2.length; _i3++) {
3495
+ var path = _Object$values2[_i3].path;
3496
+
3497
+ if (_get(stateValues, path) === UNINITIALIZED) {
3498
+ _get($state, path);
3499
+ }
3500
+ }
3501
+
3502
+ return initFuncDeps;
3503
+ }
3459
3504
 
3460
3505
  exports.DropdownMenu = DropdownMenu;
3461
3506
  exports.PlasmicIcon = PlasmicIcon;
@@ -3471,6 +3516,8 @@ exports.createUseScreenVariants = createUseScreenVariants;
3471
3516
  exports.deriveRenderOpts = deriveRenderOpts;
3472
3517
  exports.ensureGlobalVariants = ensureGlobalVariants;
3473
3518
  exports.genTranslatableString = genTranslatableString;
3519
+ exports.generateStateOnChangeProp = generateStateOnChangeProp;
3520
+ exports.generateStateValueProp = generateStateValueProp;
3474
3521
  exports.getDataProps = getDataProps;
3475
3522
  exports.hasVariant = hasVariant;
3476
3523
  exports.makeFragment = makeFragment;
@@ -3480,7 +3527,7 @@ exports.renderPlasmicSlot = renderPlasmicSlot;
3480
3527
  exports.setPlumeStrictMode = setPlumeStrictMode;
3481
3528
  exports.useButton = useButton;
3482
3529
  exports.useCheckbox = useCheckbox;
3483
- exports.useDollarState = useDollarState;
3530
+ exports.useDollarState = useVanillaDollarState;
3484
3531
  exports.useIsSSR = useIsSSR;
3485
3532
  exports.useMenu = useMenu;
3486
3533
  exports.useMenuButton = useMenuButton;