preact-sigma 6.2.1 → 6.3.1

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.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as SigmaRef, c as castProtected, d as sigma, f as Draft, h as Cleanup, i as SigmaDefinition, l as query, m as typeSymbol, n as ReadableSigma, o as SigmaState, p as Immutable, r as Sigma, s as SigmaTarget, t as Protected, u as setAutoFreeze } from "./sigma-cb2HeDjg.mjs";
1
+ import { a as SigmaRef, c as castProtected, d as sigma, f as Draft, g as Cleanup, h as AnyResource, i as SigmaDefinition, l as query, m as typeSymbol, n as ReadableSigma, o as SigmaState, p as Immutable, r as Sigma, s as SigmaTarget, t as Protected, u as setAutoFreeze } from "./sigma-thcYEnFu.mjs";
2
2
 
3
3
  //#region src/defaults.d.ts
4
4
  /**
@@ -44,7 +44,14 @@ declare function useListener<TTarget extends Listenable, TEvent extends InferEve
44
44
  //#region src/hooks/useSigma.d.ts
45
45
  /** Setup arguments and recreation dependencies for `useSigma(...)`. */
46
46
  type UseSigmaOptions<TSetup extends readonly any[] = any[]> = {
47
- /** Arguments passed to the sigma instance's `onSetup(...)` method. */setup: TSetup | (() => TSetup); /** Dependencies that recreate the sigma instance when they change. */
47
+ /**
48
+ * Arguments passed to the sigma instance's `onSetup(...)` method.
49
+ *
50
+ * Array setup arguments also drive setup cleanup and rerun. Function setup is
51
+ * evaluated for the current setup run, but it does not make captured render
52
+ * values reactive by itself; pass an array when setup inputs should rerun.
53
+ */
54
+ setup: TSetup | (() => TSetup); /** Dependencies that recreate the sigma instance when they change. */
48
55
  deps?: readonly any[];
49
56
  };
50
57
  /** Infers the accepted `useSigma(...)` call shape from a sigma class and its setup parameters. */
@@ -54,7 +61,9 @@ type UseSigmaArgs<T extends Sigma<any>> = T extends {
54
61
  /**
55
62
  * Creates or reuses a sigma instance for a component and returns its protected consumer view.
56
63
  *
57
- * Classes with `onSetup(...)` run setup in an effect and clean it up on unmount.
64
+ * Classes with `onSetup(...)` run setup in an effect and clean it up on unmount,
65
+ * so the returned instance does not need a separate `useSetup(...)` call. Array
66
+ * setup arguments rerun setup when they change; `deps` recreates the instance.
58
67
  */
59
68
  declare function useSigma<T extends Sigma<any>>(...args: UseSigmaArgs<T>): Protected<T>;
60
69
  //#endregion
@@ -72,4 +81,17 @@ type PlainObject = Record<string, unknown>;
72
81
  */
73
82
  declare function useSigmaSync<TInstance extends Sigma<any>, TInput extends PlainObject>(instance: TInstance | Protected<TInstance>, input: TInput, sync: (input: Readonly<TInput>) => void): void;
74
83
  //#endregion
75
- export { type Draft, type Immutable, InferEventType, InferListener, Listenable, Protected, ReadableSigma, Sigma, SigmaDefinition, SigmaListenable, SigmaRef, SigmaState, SigmaTarget, UseSigmaArgs, UseSigmaOptions, castProtected, listen, mergeDefaults, query, setAutoFreeze, sigma, useListener, useSigma, useSigmaSync };
84
+ //#region src/hooks/useSetup.d.ts
85
+ /** Setup callback that returns resources owned by one effect run. */
86
+ type SetupCallback = () => readonly AnyResource[];
87
+ /**
88
+ * Runs a component setup effect and disposes returned resources in reverse order.
89
+ *
90
+ * The returned resources use the same cleanup protocol as `Sigma.setup(...)`.
91
+ * Use this for resources owned directly by a component. Components that create
92
+ * a sigma instance with `useSigma(...)` do not need `useSetup(...)` for that
93
+ * instance, because `useSigma(...)` runs `onSetup(...)` automatically.
94
+ */
95
+ declare function useSetup(setup: SetupCallback, deps?: readonly any[]): void;
96
+ //#endregion
97
+ export { type AnyResource, type Cleanup, type Draft, type Immutable, InferEventType, InferListener, Listenable, Protected, ReadableSigma, SetupCallback, Sigma, SigmaDefinition, SigmaListenable, SigmaRef, SigmaState, SigmaTarget, UseSigmaArgs, UseSigmaOptions, castProtected, listen, mergeDefaults, query, setAutoFreeze, sigma, useListener, useSetup, useSigma, useSigmaSync };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as setAutoFreeze, c as listenersSymbol, i as query, n as SigmaTarget, o as sigma, r as castProtected, s as isPlainObject, t as Sigma } from "./sigma-B7kPkW-M.mjs";
1
+ import { a as setAutoFreeze, c as isPlainObject, i as query, l as listenersSymbol, n as SigmaTarget, o as sigma, r as castProtected, s as disposeResources, t as Sigma } from "./sigma-BH9WolKc.mjs";
2
2
  import { useEffect, useRef } from "preact/hooks";
3
3
  //#region src/defaults.ts
4
4
  /**
@@ -115,4 +115,20 @@ function useSigmaSync(instance, input, sync) {
115
115
  });
116
116
  }
117
117
  //#endregion
118
- export { Sigma, SigmaTarget, castProtected, listen, mergeDefaults, query, setAutoFreeze, sigma, useListener, useSigma, useSigmaSync };
118
+ //#region src/hooks/useSetup.ts
119
+ /**
120
+ * Runs a component setup effect and disposes returned resources in reverse order.
121
+ *
122
+ * The returned resources use the same cleanup protocol as `Sigma.setup(...)`.
123
+ * Use this for resources owned directly by a component. Components that create
124
+ * a sigma instance with `useSigma(...)` do not need `useSetup(...)` for that
125
+ * instance, because `useSigma(...)` runs `onSetup(...)` automatically.
126
+ */
127
+ function useSetup(setup, deps) {
128
+ useEffect(() => {
129
+ const resources = setup();
130
+ return () => disposeResources(resources);
131
+ }, deps);
132
+ }
133
+ //#endregion
134
+ export { Sigma, SigmaTarget, castProtected, listen, mergeDefaults, query, setAutoFreeze, sigma, useListener, useSetup, useSigma, useSigmaSync };
@@ -1,4 +1,4 @@
1
- import { n as ReadableSigma, p as Immutable, r as Sigma } from "./sigma-cb2HeDjg.mjs";
1
+ import { n as ReadableSigma, p as Immutable, r as Sigma } from "./sigma-thcYEnFu.mjs";
2
2
 
3
3
  //#region src/persist.d.ts
4
4
  type MaybePromise<T> = T | Promise<T>;
package/dist/persist.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { o as sigma, s as isPlainObject } from "./sigma-B7kPkW-M.mjs";
1
+ import { c as isPlainObject, o as sigma } from "./sigma-BH9WolKc.mjs";
2
2
  //#region src/persist.ts
3
3
  function createIdentityCodec() {
4
4
  return {
@@ -33,6 +33,14 @@ var SigmaListenerMap = class extends Map {
33
33
  };
34
34
  //#endregion
35
35
  //#region src/internal/utils.ts
36
+ function disposeResource(resource) {
37
+ if (typeof resource === "function") resource();
38
+ else if ("dispose" in resource) resource.dispose();
39
+ else resource[Symbol.dispose]();
40
+ }
41
+ function disposeResources(resources) {
42
+ for (let i = resources.length - 1; i >= 0; i--) disposeResource(resources[i]);
43
+ }
36
44
  function isPlainObject(value) {
37
45
  if (typeof value !== "object" || value === null) return false;
38
46
  const prototype = Object.getPrototypeOf(value);
@@ -303,11 +311,6 @@ function initializeType(type) {
303
311
  initializedPrototypes.add(prototype);
304
312
  }
305
313
  }
306
- function disposeCleanupResource(resource) {
307
- if (typeof resource === "function") resource();
308
- else if ("dispose" in resource) resource.dispose();
309
- else resource[Symbol.dispose]();
310
- }
311
314
  function defineSignalProperty(instance, key, value) {
312
315
  Object.defineProperty(instance, key + signalSuffix, { value: signal(value) });
313
316
  if (!Object.hasOwn(instance.constructor.prototype, key)) Object.defineProperty(instance.constructor.prototype, key, {
@@ -355,7 +358,7 @@ var Sigma = class {
355
358
  activeSetupInstance = previousSetupInstance;
356
359
  }
357
360
  return () => {
358
- for (let i = resources.length - 1; i >= 0; i--) disposeCleanupResource(resources[i]);
361
+ disposeResources(resources);
359
362
  };
360
363
  }
361
364
  /**
@@ -472,4 +475,4 @@ function query(method) {
472
475
  return queryMethod;
473
476
  }
474
477
  //#endregion
475
- export { setAutoFreeze as a, listenersSymbol as c, query as i, SigmaTarget as n, sigma as o, castProtected as r, isPlainObject as s, Sigma as t };
478
+ export { setAutoFreeze as a, isPlainObject as c, query as i, listenersSymbol as l, SigmaTarget as n, sigma as o, castProtected as r, disposeResources as s, Sigma as t };
@@ -3,7 +3,14 @@ import { Patch } from "immer";
3
3
 
4
4
  //#region src/internal/utils.d.ts
5
5
  type AnyFunction = (...args: any[]) => any;
6
+ /** Cleanup function returned by setup-owned resources and run during teardown. */
6
7
  type Cleanup = () => void;
8
+ /**
9
+ * Resource shape accepted from `onSetup(...)` and `useSetup(...)`.
10
+ *
11
+ * Teardown disposes resources in reverse order and accepts cleanup functions,
12
+ * objects with `dispose()`, and objects with `[Symbol.dispose]()`.
13
+ */
7
14
  type AnyResource = Cleanup | {
8
15
  dispose(): void;
9
16
  } | {
@@ -172,4 +179,4 @@ type Protected<T extends Sigma<any>> = BrandProtected<T extends {
172
179
  };
173
180
  } ? { readonly [K in keyof T as K extends ProtectedKey ? never : K]: K extends typeof typeSymbol ? T[K] : K extends keyof TState ? Immutable<T[K]> : T[K] extends AnyFunction ? (...params: Parameters<T[K]>) => Immutable<ReturnType<T[K]>> : Immutable<T[K]> } : never>;
174
181
  //#endregion
175
- export { SigmaRef as a, castProtected as c, sigma as d, Draft as f, Cleanup as h, SigmaDefinition as i, query as l, typeSymbol as m, ReadableSigma as n, SigmaState as o, Immutable as p, Sigma as r, SigmaTarget as s, Protected as t, setAutoFreeze as u };
182
+ export { SigmaRef as a, castProtected as c, sigma as d, Draft as f, Cleanup as g, AnyResource as h, SigmaDefinition as i, query as l, typeSymbol as m, ReadableSigma as n, SigmaState as o, Immutable as p, Sigma as r, SigmaTarget as s, Protected as t, setAutoFreeze as u };
package/docs/context.md CHANGED
@@ -53,9 +53,10 @@
53
53
  - Publish unpublished changes before `await`, `emit(...)`, promise resolution, or another instance's action: `this.commit()`.
54
54
  - React to committed state changes: `sigma.subscribe(instance, handler)` or `sigma.subscribe(instance, key, handler)`.
55
55
  - Read one top-level state property as a `ReadonlySignal`: `sigma.getSignal(instance, key)`.
56
- - Own timers, listeners, subscriptions, or nested setup: `onSetup(...)` plus `setup(...)`.
57
- - Use a sigma instance inside a component: `useSigma(...)`.
56
+ - Own model lifecycle resources: `onSetup(...)` plus `setup(...)`.
57
+ - Use a component-owned sigma instance: `useSigma(...)`, which runs `onSetup(...)` automatically.
58
58
  - Synchronize changed component data into a sigma instance after the initial render: `useSigmaSync(instance, input, sync)`.
59
+ - Own component-local setup resources: `useSetup(...)`.
59
60
  - Cast an instance to its readonly consumer view outside a component: `castProtected(instance)`.
60
61
  - Subscribe to sigma or DOM events in a component: `useListener(...)`.
61
62
  - Subscribe outside components: `listen(instance, ...)`.
@@ -72,7 +73,9 @@
72
73
  - Use ordinary actions for routine writes. Reserve `sigma.captureState(...)` and `sigma.replaceState(...)` for replay, reset, restore, or undo-like flows on committed top-level state.
73
74
  - Emit directly from standalone `SigmaTarget` instances. In subclasses, emit from actions that have no unpublished draft changes. After mutating state, publish first with `this.commit(); this.emit(...)`.
74
75
  - Prefer `listen(...)` for external event subscriptions. It works with sigma targets and DOM targets.
75
- - Put owned side effects in `onSetup(...)`.
76
+ - Put model-owned side effects in `onSetup(...)`.
77
+ - Use `useSetup(...)` when a component owns setup resources directly. The callback returns cleanup resources, and teardown disposes them in reverse order.
78
+ - A sigma instance created with `useSigma(...)` already runs its `onSetup(...)` method. Do not call `instance.setup(...)` for that same instance from `useSetup(...)`, because that starts a second setup lifecycle.
76
79
  - Use `useSigmaSync(...)` when a component-owned sigma instance is initialized from external props or hook data and needs to receive later changes through an action. Pass a plain object with stable keys; values are compared with `Object.is(...)`, and a recreated instance treats the current input as its new baseline.
77
80
  - Use `sigma.subscribe(this, ...)` inside `onSetup(...)` when a setup-owned side effect should react to future committed publishes. Return that cleanup so the subscription stops with setup.
78
81
  ```ts
@@ -91,6 +94,7 @@
91
94
  - Reaching for `sigma.getSignal(instance, key)` when direct property reads already cover the use case.
92
95
  - Crossing `emit(...)`, `await`, promise resolution, or another instance's action with unpublished changes. Publish them first with `this.commit()`.
93
96
  - Starting side effects during construction instead of through explicit `setup(...)`.
97
+ - Calling `setup(...)` manually for an instance created by `useSigma(...)`.
94
98
  - Encoding storage, hydration, or migration policy directly into model classes.
95
99
  - Relying on computeds or queries to observe unpublished draft changes inside actions.
96
100
  - Treating query calls as memoized across invocations.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "preact-sigma",
3
- "version": "6.2.1",
3
+ "version": "6.3.1",
4
4
  "keywords": [],
5
5
  "license": "MIT",
6
6
  "author": "Alec Larson",
@@ -24,6 +24,14 @@
24
24
  "import": "./dist/persist.mjs"
25
25
  }
26
26
  },
27
+ "scripts": {
28
+ "build": "tsdown",
29
+ "test": "vitest run",
30
+ "typecheck": "tsc --noEmit --allowImportingTsExtensions",
31
+ "fmt": "oxfmt",
32
+ "lint": "oxlint",
33
+ "prepublishOnly": "pnpm build"
34
+ },
27
35
  "devDependencies": {
28
36
  "@preact/preset-vite": "^2.10.5",
29
37
  "@types/node": "^25.5.0",
@@ -42,11 +50,5 @@
42
50
  "immer": ">=11",
43
51
  "preact": ">=10"
44
52
  },
45
- "scripts": {
46
- "build": "tsdown",
47
- "test": "vitest run",
48
- "typecheck": "tsc --noEmit --allowImportingTsExtensions",
49
- "fmt": "oxfmt",
50
- "lint": "oxlint"
51
- }
52
- }
53
+ "packageManager": "pnpm@11.5.1"
54
+ }