@rohal12/spindle 0.51.3 → 0.52.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.
Files changed (66) hide show
  1. package/dist/pkg/format.js +1 -1
  2. package/dist/pkg/headless.js +4833 -1603
  3. package/dist/pkg/macro-registry.json +7 -7
  4. package/dist/pkg/story-variables.js +1658 -189
  5. package/package.json +5 -2
  6. package/src/automation/runner.ts +2 -1
  7. package/src/class-registry.ts +277 -90
  8. package/src/components/Passage.tsx +2 -2
  9. package/src/components/PassageDialog.tsx +2 -5
  10. package/src/components/StoryInterface.tsx +2 -4
  11. package/src/components/macros/Button.tsx +9 -32
  12. package/src/components/macros/Checkbox.tsx +10 -4
  13. package/src/components/macros/Computed.tsx +19 -13
  14. package/src/components/macros/Dialog.tsx +4 -1
  15. package/src/components/macros/For.tsx +33 -4
  16. package/src/components/macros/If.tsx +8 -0
  17. package/src/components/macros/Include.tsx +15 -24
  18. package/src/components/macros/MacroError.tsx +2 -1
  19. package/src/components/macros/MacroLink.tsx +14 -46
  20. package/src/components/macros/Meter.tsx +26 -40
  21. package/src/components/macros/Nobr.tsx +1 -0
  22. package/src/components/macros/PassageDisplay.tsx +3 -0
  23. package/src/components/macros/Print.tsx +4 -0
  24. package/src/components/macros/Radiobutton.tsx +27 -2
  25. package/src/components/macros/SaveManager.tsx +39 -14
  26. package/src/components/macros/Span.tsx +1 -0
  27. package/src/components/macros/StoryTitle.tsx +1 -0
  28. package/src/components/macros/Switch.tsx +13 -0
  29. package/src/components/macros/Unset.tsx +30 -10
  30. package/src/components/macros/VarDisplay.tsx +21 -4
  31. package/src/components/macros/Watch.tsx +88 -40
  32. package/src/components/macros/Widget.tsx +20 -1
  33. package/src/components/macros/WidgetInvocation.tsx +20 -158
  34. package/src/components/macros/arg-utils.ts +226 -0
  35. package/src/components/macros/detached-body.tsx +68 -0
  36. package/src/components/macros/option-utils.ts +10 -5
  37. package/src/define-macro.ts +44 -38
  38. package/src/execute-mutation.ts +499 -28
  39. package/src/expression.ts +88 -272
  40. package/src/hooks/use-action.ts +18 -3
  41. package/src/hooks/use-interpolate.ts +36 -5
  42. package/src/index.tsx +10 -1
  43. package/src/interpolation.ts +394 -96
  44. package/src/js-lexer.ts +1460 -0
  45. package/src/markup/code-attributes.ts +64 -0
  46. package/src/markup/markdown.ts +188 -9
  47. package/src/markup/render.tsx +552 -113
  48. package/src/markup/tokenizer.ts +601 -119
  49. package/src/prng.ts +8 -8
  50. package/src/registry.ts +35 -0
  51. package/src/saves/save-manager.ts +368 -153
  52. package/src/saves/storage.ts +24 -7
  53. package/src/saves/types.ts +20 -6
  54. package/src/store.ts +549 -137
  55. package/src/story-api.ts +46 -81
  56. package/src/story-init.ts +1 -1
  57. package/src/story-variables.ts +98 -102
  58. package/src/triggers.ts +6 -2
  59. package/src/utils/error-message.ts +12 -0
  60. package/src/utils/live-locals.ts +10 -3
  61. package/src/utils/namespace.ts +71 -0
  62. package/src/utils/object-path.ts +194 -0
  63. package/src/utils/stable-key.ts +82 -0
  64. package/src/widgets/widget-registry.ts +9 -0
  65. package/types/index.d.ts +43 -7
  66. package/types/tooling.d.ts +1 -0
package/src/prng.ts CHANGED
@@ -9,11 +9,13 @@
9
9
  // Core algorithm
10
10
  // ---------------------------------------------------------------------------
11
11
 
12
+ const MULBERRY_STEP = 0x6d2b79f5;
13
+
12
14
  /** Mulberry32: fast, high-quality 32-bit PRNG. */
13
15
  function mulberry32(seed: number): () => number {
14
16
  let t = seed | 0;
15
17
  return () => {
16
- t = (t + 0x6d2b79f5) | 0;
18
+ t = (t + MULBERRY_STEP) | 0;
17
19
  let r = Math.imul(t ^ (t >>> 15), t | 1);
18
20
  r ^= r + Math.imul(r ^ (r >>> 7), r | 61);
19
21
  return ((r ^ (r >>> 14)) >>> 0) / 0x100000000;
@@ -77,14 +79,12 @@ export function initPRNG(seed?: string, useEntropy = true): void {
77
79
  */
78
80
  export function restorePRNG(seed: string, pull: number): void {
79
81
  currentSeed = seed;
80
- currentPull = 0;
81
- generator = mulberry32(hashSeed(seed));
82
+ // Fast-forward in constant time: each pull adds MULBERRY_STEP to the
83
+ // 32-bit state, so `pull` pulls add pull × MULBERRY_STEP (mod 2^32). A
84
+ // loop would hang on the large counts an imported save may hold.
85
+ const steps = Math.imul(pull % 0x100000000, MULBERRY_STEP);
86
+ generator = mulberry32((hashSeed(seed) + steps) | 0);
82
87
  enabled = true;
83
-
84
- // Fast-forward
85
- for (let i = 0; i < pull; i++) {
86
- generator();
87
- }
88
88
  currentPull = pull;
89
89
  }
90
90
 
package/src/registry.ts CHANGED
@@ -22,6 +22,41 @@ export function getMacro(name: string): ComponentType<MacroProps> | undefined {
22
22
  return registry.get(name.toLowerCase());
23
23
  }
24
24
 
25
+ /**
26
+ * What a macro's text form gets: see MacroDefinition.text. Evaluation runs
27
+ * in the scope of the attribute (or label) being resolved.
28
+ */
29
+ export interface MacroTextContext {
30
+ /** Evaluate an expression in the current scope. */
31
+ evaluate: (expr: string) => unknown;
32
+ /**
33
+ * The text of AST nodes (a body or branch) in the current scope, with
34
+ * `locals` (keys without `@`) added on top of the current locals.
35
+ */
36
+ renderText: (nodes: ASTNode[], locals?: Record<string, unknown>) => string;
37
+ }
38
+
39
+ /** A macro's text form: the string it stands for in text-only markup. */
40
+ export type MacroTextRenderer = (
41
+ props: MacroProps,
42
+ ctx: MacroTextContext,
43
+ ) => string;
44
+
45
+ const textRegistry = new Map<string, MacroTextRenderer>();
46
+
47
+ /** Register (or, with undefined, remove) the text form of a macro. */
48
+ export function registerMacroText(
49
+ name: string,
50
+ text: MacroTextRenderer | undefined,
51
+ ): void {
52
+ if (text) textRegistry.set(name.toLowerCase(), text);
53
+ else textRegistry.delete(name.toLowerCase());
54
+ }
55
+
56
+ export function getMacroText(name: string): MacroTextRenderer | undefined {
57
+ return textRegistry.get(name.toLowerCase());
58
+ }
59
+
25
60
  const subMacros = new Set<string>();
26
61
 
27
62
  export function registerSubMacro(name: string): void {