oracular 0.12.1 → 0.13.0

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.
package/dist/index.d.cts CHANGED
@@ -395,7 +395,11 @@ type Migrate = (stored: unknown, version: number) => EngineState;
395
395
  * ```
396
396
  */
397
397
  interface DeserializeOptions {
398
- /** The app's current config. Validated, swapped in, and used to prune signals and intents no longer declared. */
398
+ /**
399
+ * The app's current config. Validated, swapped in, and used to prune signals and intents no
400
+ * longer declared; the stored snapshot is then not read, so a key or value a newer release wrote
401
+ * into it does not stop the load.
402
+ */
399
403
  config?: EngineConfig;
400
404
  /**
401
405
  * Called when the stored version is neither `STATE_VERSION`, nor one this library migrates
@@ -850,11 +854,14 @@ declare function serialize(state: EngineState): string;
850
854
  /**
851
855
  * Restores a state saved with {@link serialize}.
852
856
  *
853
- * Always pass the app's current `config`: it is validated and replaces the stored snapshot (the
854
- * stored one is read without the checks that refuse a config that cannot work, so a state saved
855
- * before those checks existed still loads),
856
- * intents and signals no longer declared are dropped (α and β are recomputed from the kept
857
- * contributions), and newly declared intents start at their prior. States saved by oracular
857
+ * Always pass the app's current `config`: it is validated and replaces the stored snapshot,
858
+ * which is then not read at all, so a state written by a newer release, with a config key or
859
+ * value this one does not know, still loads after a rollback. Intents and signals no longer
860
+ * declared are dropped (α and β are recomputed from the kept contributions), and newly declared
861
+ * intents start at their prior. Without a config the stored snapshot runs the engine: it is read
862
+ * without the checks that refuse a config that cannot work, so a state saved before those checks
863
+ * existed still loads, but a key the library does not know is an error, since the engine would
864
+ * otherwise run without an option the state was built under. States saved by oracular
858
865
  * 0.1.0 to 0.11.x are upgraded to the current shape on their own, and a state one version newer
859
866
  * than {@link STATE_VERSION} (written by the next release, read after a rollback) is read as the
860
867
  * current one, ignoring the fields it adds; `migrate` is only for a version this library does
package/dist/index.d.ts CHANGED
@@ -395,7 +395,11 @@ type Migrate = (stored: unknown, version: number) => EngineState;
395
395
  * ```
396
396
  */
397
397
  interface DeserializeOptions {
398
- /** The app's current config. Validated, swapped in, and used to prune signals and intents no longer declared. */
398
+ /**
399
+ * The app's current config. Validated, swapped in, and used to prune signals and intents no
400
+ * longer declared; the stored snapshot is then not read, so a key or value a newer release wrote
401
+ * into it does not stop the load.
402
+ */
399
403
  config?: EngineConfig;
400
404
  /**
401
405
  * Called when the stored version is neither `STATE_VERSION`, nor one this library migrates
@@ -850,11 +854,14 @@ declare function serialize(state: EngineState): string;
850
854
  /**
851
855
  * Restores a state saved with {@link serialize}.
852
856
  *
853
- * Always pass the app's current `config`: it is validated and replaces the stored snapshot (the
854
- * stored one is read without the checks that refuse a config that cannot work, so a state saved
855
- * before those checks existed still loads),
856
- * intents and signals no longer declared are dropped (α and β are recomputed from the kept
857
- * contributions), and newly declared intents start at their prior. States saved by oracular
857
+ * Always pass the app's current `config`: it is validated and replaces the stored snapshot,
858
+ * which is then not read at all, so a state written by a newer release, with a config key or
859
+ * value this one does not know, still loads after a rollback. Intents and signals no longer
860
+ * declared are dropped (α and β are recomputed from the kept contributions), and newly declared
861
+ * intents start at their prior. Without a config the stored snapshot runs the engine: it is read
862
+ * without the checks that refuse a config that cannot work, so a state saved before those checks
863
+ * existed still loads, but a key the library does not know is an error, since the engine would
864
+ * otherwise run without an option the state was built under. States saved by oracular
858
865
  * 0.1.0 to 0.11.x are upgraded to the current shape on their own, and a state one version newer
859
866
  * than {@link STATE_VERSION} (written by the next release, read after a rollback) is read as the
860
867
  * current one, ignoring the fields it adds; `migrate` is only for a version this library does
package/dist/index.js CHANGED
@@ -1003,9 +1003,9 @@ function deserialize(json, opts = {}) {
1003
1003
  stored = opts.migrate(parsed, parsed.version);
1004
1004
  }
1005
1005
  }
1006
- const raw = parseState(stored);
1007
- const config = opts.config === void 0 ? raw.config : normalizeConfig(opts.config);
1008
- return requireComputable(reconcile(raw, config));
1006
+ const config = opts.config === void 0 ? void 0 : normalizeConfig(opts.config);
1007
+ const raw = parseState(stored, config);
1008
+ return requireComputable(reconcile(raw, raw.config));
1009
1009
  }
1010
1010
  function typeError2(path, message) {
1011
1011
  throw new TypeError(`oracular: ${path} ${message}`);
@@ -1114,16 +1114,15 @@ function clockState(value, path) {
1114
1114
  behindAt: nullOrFinite(r.behindAt, `${path}.behindAt`)
1115
1115
  };
1116
1116
  }
1117
- function parseState(value) {
1117
+ function parseState(value, config) {
1118
1118
  const r = record(value, "state");
1119
1119
  if (r.version !== STATE_VERSION) {
1120
1120
  throw new RangeError(`oracular: state.version must be ${STATE_VERSION} after migration`);
1121
1121
  }
1122
+ const snapshot = record(r.config, "state.config");
1122
1123
  return {
1123
1124
  version: STATE_VERSION,
1124
- // Without the strict checks: a config this release would refuse at createState still loads
1125
- // when it is only stored, and the config passed in replaces it anyway.
1126
- config: normalizeConfig(r.config, false),
1125
+ config: config ?? normalizeConfig(snapshot, false),
1127
1126
  intents: mapOwn(r.intents, "state.intents", intentState),
1128
1127
  episode: episodeState(r.episode, "state.episode"),
1129
1128
  clock: clockState(r.clock, "state.clock")