@xynogen/pix-todo 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -14,6 +14,8 @@ pi install npm:@xynogen/pix-todo
14
14
 
15
15
  ## Full distro
16
16
 
17
+ Source: [github.com/xynogen/pix-mono](https://github.com/xynogen/pix-mono)
18
+
17
19
  To install the complete pix suite (all packages + Pi itself):
18
20
 
19
21
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xynogen/pix-todo",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Pi tool — durable execution checklist (todo)",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/once.ts CHANGED
@@ -1,15 +1,25 @@
1
1
  /**
2
- * Idempotency guard for extension activation.
2
+ * Per-instance idempotency guard for extension activation.
3
3
  *
4
- * pix-core (the meta-package) invokes this package's factory in addition to a
5
- * possible direct install. Pi's loader uses jiti with `moduleCache: false`, so
6
- * each load pass re-evaluates modules a plain module-level flag would not be
7
- * shared. The dedupe key therefore lives on `globalThis`, which persists for
8
- * the lifetime of the process across all load passes.
4
+ * pix-core (the meta-package) invokes this package's factory, and a standalone
5
+ * install makes Pi invoke it again sometimes against the SAME `pi`. We must
6
+ * dedupe that. But Pi rebuilds the extension runtime on /new, /resume, /fork,
7
+ * and /reload, handing the factory a BRAND-NEW `pi`; that must re-register.
8
+ *
9
+ * Keying the registry on the `pi` instance satisfies both: same instance =>
10
+ * skip, new instance => run. The registry lives on globalThis because jiti
11
+ * (`moduleCache: false`) re-evaluates this module on every load pass, so a
12
+ * module-scoped WeakMap would not be shared between the aggregator pass and the
13
+ * standalone pass within a single session.
9
14
  */
10
- export function once(key: string, fn: () => void): void {
11
- const g = globalThis as { __pixLoaded?: Set<string> };
12
- const loaded = (g.__pixLoaded ??= new Set<string>());
15
+ export function once(pi: object, key: string, fn: () => void): void {
16
+ const g = globalThis as { __pixOnce?: WeakMap<object, Set<string>> };
17
+ const registry = (g.__pixOnce ??= new WeakMap<object, Set<string>>());
18
+ let loaded = registry.get(pi);
19
+ if (!loaded) {
20
+ loaded = new Set<string>();
21
+ registry.set(pi, loaded);
22
+ }
13
23
  if (loaded.has(key)) return;
14
24
  loaded.add(key);
15
25
  fn();
package/src/todo.test.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { beforeEach, describe, expect, test } from "bun:test";
2
2
  import registerTodo, { renderTodoLines, type TodoItem } from "./todo.ts";
3
3
 
4
- // registerTodo wraps its body in once("pix-todo") — a process-wide globalThis
5
- // guard that dedupes activation across pix-core + a standalone install. Tests
6
- // re-register a fresh host per case, so clear the registry first to let each
7
- // registerTodo run (mirrors pix-core/once.test.ts clearing __pixLoaded).
4
+ // registerTodo wraps its body in once(pi, "pix-todo") — a per-instance
5
+ // WeakMap guard that dedupes activation across pix-core + a standalone install.
6
+ // Tests re-register a fresh host per case. Clear the registry between tests so
7
+ // that the same pi object can be re-used without cross-test interference.
8
8
  beforeEach(() => {
9
- delete (globalThis as { __pixLoaded?: Set<string> }).__pixLoaded;
9
+ delete (globalThis as { __pixOnce?: WeakMap<object, Set<string>> }).__pixOnce;
10
10
  });
11
11
 
12
12
  // Stub theme tags each fragment with its color/bold so assertions can verify
package/src/todo.ts CHANGED
@@ -69,7 +69,7 @@ const parseItems = (raw: string): string[] =>
69
69
  .filter(Boolean);
70
70
 
71
71
  export default function registerTodo(pi: ExtensionAPI): void {
72
- once("pix-todo", () => {
72
+ once(pi, "pix-todo", () => {
73
73
  let todos: TodoItem[] = [];
74
74
  let nextTodoId = 1;
75
75