@soda-gql/common 0.0.9 → 0.2.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 (40) hide show
  1. package/README.md +121 -0
  2. package/dist/canonical-id-BFcryTw5.cjs +2 -1
  3. package/dist/canonical-id-BFcryTw5.cjs.map +1 -0
  4. package/dist/{canonical-id/index.cjs → canonical-id.cjs} +2 -2
  5. package/dist/{canonical-id/index.d.cts → canonical-id.d.cts} +1 -1
  6. package/dist/{canonical-id/index.d.mts → canonical-id.d.mts} +1 -1
  7. package/dist/{canonical-id/index.mjs → canonical-id.mjs} +2 -2
  8. package/dist/index-DaAp2rNj.d.cts.map +1 -1
  9. package/dist/index.cjs +265 -1
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.cts +216 -1
  12. package/dist/index.d.cts.map +1 -0
  13. package/dist/index.d.mts +216 -1
  14. package/dist/index.d.mts.map +1 -0
  15. package/dist/index.mjs +256 -1
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/portable-C_7gJWmz.cjs +2 -1
  18. package/dist/portable-C_7gJWmz.cjs.map +1 -0
  19. package/dist/portable-Dbo3u2CQ.mjs.map +1 -1
  20. package/dist/{portable/index.cjs → portable.cjs} +1 -1
  21. package/dist/{portable/index.d.cts → portable.d.cts} +1 -1
  22. package/dist/{portable/index.d.mts → portable.d.mts} +1 -1
  23. package/dist/{portable/index.mjs → portable.mjs} +1 -1
  24. package/dist/utils-CmLf7LU5.cjs +2 -1
  25. package/dist/utils-CmLf7LU5.cjs.map +1 -0
  26. package/dist/{utils/index.cjs → utils.cjs} +1 -1
  27. package/dist/{utils/index.d.cts → utils.d.cts} +1 -1
  28. package/dist/{utils/index.d.mts → utils.d.mts} +1 -1
  29. package/dist/{utils/index.mjs → utils.mjs} +1 -1
  30. package/dist/zod-CynYgOoN.cjs +2 -1
  31. package/dist/zod-CynYgOoN.cjs.map +1 -0
  32. package/dist/zod.cjs +3 -0
  33. package/dist/zod.d.cts +2 -0
  34. package/dist/zod.d.mts +2 -0
  35. package/dist/zod.mjs +3 -0
  36. package/package.json +49 -26
  37. package/dist/zod/index.cjs +0 -3
  38. package/dist/zod/index.d.cts +0 -2
  39. package/dist/zod/index.d.mts +0 -2
  40. package/dist/zod/index.mjs +0 -3
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # @soda-gql/common
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@soda-gql/common.svg)](https://www.npmjs.com/package/@soda-gql/common)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Shared utilities and types for the soda-gql ecosystem.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ bun add @soda-gql/common
12
+ ```
13
+
14
+ > **Note**: This package is primarily used internally by other soda-gql packages. Direct usage is only needed for advanced integration scenarios.
15
+
16
+ ## Overview
17
+
18
+ This package provides shared utilities used across the soda-gql ecosystem:
19
+
20
+ - Portable utilities for cross-environment compatibility
21
+ - Canonical ID generation and parsing
22
+ - Path building utilities
23
+ - Zod validation helpers
24
+
25
+ ## Exports
26
+
27
+ ### Main Entry (`@soda-gql/common`)
28
+
29
+ Common types and utilities:
30
+
31
+ ```typescript
32
+ import { ... } from "@soda-gql/common";
33
+ ```
34
+
35
+ ### Portable (`@soda-gql/common/portable`)
36
+
37
+ Cross-environment utilities:
38
+
39
+ ```typescript
40
+ import { ... } from "@soda-gql/common/portable";
41
+ ```
42
+
43
+ ### Canonical ID (`@soda-gql/common/canonical-id`)
44
+
45
+ Canonical ID generation and parsing:
46
+
47
+ ```typescript
48
+ import { createCanonicalId, parseCanonicalId } from "@soda-gql/common/canonical-id";
49
+
50
+ // Create a canonical ID
51
+ const id = createCanonicalId("/path/to/file.ts", "userQuery");
52
+ // Result: "/path/to/file.ts::userQuery"
53
+
54
+ // Parse a canonical ID
55
+ const parsed = parseCanonicalId(id);
56
+ // Result: { filePath: "/path/to/file.ts", astPath: "userQuery" }
57
+ ```
58
+
59
+ ### Utils (`@soda-gql/common/utils`)
60
+
61
+ General utility functions:
62
+
63
+ ```typescript
64
+ import { ... } from "@soda-gql/common/utils";
65
+ ```
66
+
67
+ ### Zod (`@soda-gql/common/zod`)
68
+
69
+ Zod validation helpers:
70
+
71
+ ```typescript
72
+ import { ... } from "@soda-gql/common/zod";
73
+ ```
74
+
75
+ ### Scheduler (Effect System)
76
+
77
+ Generator-based effect system for scheduling sync and async operations:
78
+
79
+ ```typescript
80
+ import {
81
+ createSyncScheduler,
82
+ createAsyncScheduler,
83
+ PureEffect,
84
+ DeferEffect,
85
+ ParallelEffect,
86
+ YieldEffect,
87
+ } from "@soda-gql/common";
88
+
89
+ // Sync usage
90
+ const syncScheduler = createSyncScheduler();
91
+ const result = syncScheduler.run(function* () {
92
+ const a = yield* new PureEffect(1).run();
93
+ const b = yield* new PureEffect(2).run();
94
+ return a + b;
95
+ });
96
+
97
+ // Async usage with parallel effects
98
+ const asyncScheduler = createAsyncScheduler();
99
+ const asyncResult = await asyncScheduler.run(function* () {
100
+ const data = yield* new DeferEffect(fetchData()).run();
101
+ yield* new YieldEffect().run(); // Yield to event loop
102
+ return processData(data);
103
+ });
104
+ ```
105
+
106
+ ### Test Utilities (`@soda-gql/common/test`)
107
+
108
+ Shared test utilities for soda-gql packages (internal use):
109
+
110
+ ```typescript
111
+ import { createTempDir, TestSuite } from "@soda-gql/common/test";
112
+ ```
113
+
114
+ ## Related Packages
115
+
116
+ - [@soda-gql/core](../core) - Core types and utilities
117
+ - [@soda-gql/builder](../builder) - Static analysis engine
118
+
119
+ ## License
120
+
121
+ MIT
@@ -220,4 +220,5 @@ Object.defineProperty(exports, 'createPathTracker', {
220
220
  get: function () {
221
221
  return createPathTracker;
222
222
  }
223
- });
223
+ });
224
+ //# sourceMappingURL=canonical-id-BFcryTw5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-id-BFcryTw5.cjs","names":["CanonicalIdSchema: z.ZodType<CanonicalId>","z","normalizePath","scopeStack: ScopeFrame[]","frame: ScopeFrame","exportBinding: string | undefined"],"sources":["../src/canonical-id/canonical-id.ts","../src/canonical-id/path-tracker.ts"],"sourcesContent":["import { isAbsolute, resolve } from \"node:path\";\nimport z from \"zod\";\nimport { normalizePath } from \"../utils\";\n\nexport type CanonicalId = string & { readonly __brand: \"CanonicalId\" };\n\nconst canonicalIdSeparator = \"::\" as const;\n\nexport const CanonicalIdSchema: z.ZodType<CanonicalId> = z.string() as unknown as z.ZodType<CanonicalId>;\n\n// Type-safe schema for CanonicalId - validates as string but types as branded\nexport const createCanonicalId = (filePath: string, astPath: string): CanonicalId => {\n if (!isAbsolute(filePath)) {\n throw new Error(\"[INTERNAL] CANONICAL_ID_REQUIRES_ABSOLUTE_PATH\");\n }\n\n const resolved = resolve(filePath);\n const normalized = normalizePath(resolved);\n\n // Create a 2-part ID: {absPath}::{astPath}\n // astPath uniquely identifies the definition's location in the AST (e.g., \"MyComponent.useQuery.def\")\n const idParts = [normalized, astPath];\n\n return idParts.join(canonicalIdSeparator) as CanonicalId;\n};\n","/**\n * Canonical path tracker for AST traversal.\n *\n * This module provides a stateful helper that tracks scope information during\n * AST traversal to generate canonical IDs. It's designed to integrate with\n * existing plugin visitor patterns (Babel, SWC, TypeScript) without requiring\n * a separate AST traversal.\n *\n * Usage pattern:\n * 1. Plugin creates tracker at file/program entry\n * 2. Plugin calls enterScope/exitScope during its traversal\n * 3. Plugin calls registerDefinition when discovering GQL definitions\n * 4. Tracker provides canonical ID information\n */\n\nimport type { CanonicalId } from \"./canonical-id\";\nimport { createCanonicalId } from \"./canonical-id\";\n\n/**\n * Scope frame for tracking AST path segments\n */\nexport type ScopeFrame = {\n /** Name segment (e.g., \"MyComponent\", \"useQuery\", \"arrow#1\") */\n readonly nameSegment: string;\n /** Kind of scope */\n readonly kind: \"function\" | \"class\" | \"variable\" | \"property\" | \"method\" | \"expression\";\n /** Occurrence index for disambiguation */\n readonly occurrence: number;\n};\n\n/**\n * Opaque handle for scope tracking\n */\nexport type ScopeHandle = {\n readonly __brand: \"ScopeHandle\";\n readonly depth: number;\n};\n\n/**\n * Canonical path tracker interface\n */\nexport interface CanonicalPathTracker {\n /**\n * Enter a new scope during traversal\n * @param options Scope information\n * @returns Handle to use when exiting the scope\n */\n enterScope(options: { segment: string; kind: ScopeFrame[\"kind\"]; stableKey?: string }): ScopeHandle;\n\n /**\n * Exit a scope during traversal\n * @param handle Handle returned from enterScope\n */\n exitScope(handle: ScopeHandle): void;\n\n /**\n * Register a definition discovered during traversal\n * @returns Definition metadata including astPath and canonical ID information\n */\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n };\n\n /**\n * Resolve a canonical ID from an astPath\n * @param astPath AST path string\n * @returns Canonical ID\n */\n resolveCanonicalId(astPath: string): CanonicalId;\n\n /**\n * Register an export binding\n * @param local Local variable name\n * @param exported Exported name\n */\n registerExportBinding(local: string, exported: string): void;\n\n /**\n * Get current scope depth\n * @returns Current depth (0 = top level)\n */\n currentDepth(): number;\n}\n\n/**\n * Build AST path from scope stack (internal helper)\n */\nconst _buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n\n/**\n * Create a canonical path tracker\n *\n * @param options Configuration options\n * @returns Tracker instance\n *\n * @example\n * ```typescript\n * // In a Babel plugin\n * const tracker = createCanonicalTracker({ filePath: state.filename });\n *\n * const visitor = {\n * FunctionDeclaration: {\n * enter(path) {\n * const handle = tracker.enterScope({\n * segment: path.node.id.name,\n * kind: 'function'\n * });\n * },\n * exit(path) {\n * tracker.exitScope(handle);\n * }\n * }\n * };\n * ```\n */\nexport const createCanonicalTracker = (options: {\n filePath: string;\n getExportName?: (localName: string) => string | undefined;\n}): CanonicalPathTracker => {\n const { filePath, getExportName } = options;\n\n // Scope stack\n const scopeStack: ScopeFrame[] = [];\n\n // Occurrence counters for disambiguating duplicate names\n const occurrenceCounters = new Map<string, number>();\n\n // Used paths for ensuring uniqueness\n const usedPaths = new Set<string>();\n\n // Export bindings map\n const exportBindings = new Map<string, string>();\n\n const getNextOccurrence = (key: string): number => {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n };\n\n const ensureUniquePath = (basePath: string): string => {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n };\n\n return {\n enterScope({ segment, kind, stableKey }): ScopeHandle {\n const key = stableKey ?? `${kind}:${segment}`;\n const occurrence = getNextOccurrence(key);\n\n const frame: ScopeFrame = {\n nameSegment: segment,\n kind,\n occurrence,\n };\n\n scopeStack.push(frame);\n\n return {\n __brand: \"ScopeHandle\",\n depth: scopeStack.length - 1,\n } as ScopeHandle;\n },\n\n exitScope(handle: ScopeHandle): void {\n // Validate handle depth matches current stack\n if (handle.depth !== scopeStack.length - 1) {\n throw new Error(`[INTERNAL] Invalid scope exit: expected depth ${scopeStack.length - 1}, got ${handle.depth}`);\n }\n scopeStack.pop();\n },\n\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n } {\n const basePath = _buildAstPath(scopeStack);\n const astPath = ensureUniquePath(basePath);\n const isTopLevel = scopeStack.length === 0;\n\n // Check export binding if provided\n let exportBinding: string | undefined;\n if (getExportName && isTopLevel) {\n // For top-level definitions, try to get export name\n // This is a simplified version - real logic depends on how the definition is bound\n exportBinding = undefined;\n }\n\n return {\n astPath,\n isTopLevel,\n exportBinding,\n };\n },\n\n resolveCanonicalId(astPath: string): CanonicalId {\n return createCanonicalId(filePath, astPath);\n },\n\n registerExportBinding(local: string, exported: string): void {\n exportBindings.set(local, exported);\n },\n\n currentDepth(): number {\n return scopeStack.length;\n },\n };\n};\n\n/**\n * Helper to create occurrence tracker (for backward compatibility)\n */\nexport const createOccurrenceTracker = (): {\n getNextOccurrence: (key: string) => number;\n} => {\n const occurrenceCounters = new Map<string, number>();\n\n return {\n getNextOccurrence(key: string): number {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n },\n };\n};\n\n/**\n * Helper to create path tracker (for backward compatibility)\n */\nexport const createPathTracker = (): {\n ensureUniquePath: (basePath: string) => string;\n} => {\n const usedPaths = new Set<string>();\n\n return {\n ensureUniquePath(basePath: string): string {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n },\n };\n};\n\n/**\n * Build AST path from scope stack (for backward compatibility)\n */\nexport const buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,uBAAuB;AAE7B,MAAaA,oBAA4CC,YAAE,QAAQ;AAGnE,MAAa,qBAAqB,UAAkB,YAAiC;AACnF,KAAI,2BAAY,SAAS,EAAE;AACzB,QAAM,IAAI,MAAM,iDAAiD;;CAGnE,MAAM,kCAAmB,SAAS;CAClC,MAAM,aAAaC,4BAAc,SAAS;CAI1C,MAAM,UAAU,CAAC,YAAY,QAAQ;AAErC,QAAO,QAAQ,KAAK,qBAAqB;;;;;;;;ACkE3C,MAAM,iBAAiB,UAAyC;AAC9D,QAAO,MAAM,KAAK,UAAU,MAAM,YAAY,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B1D,MAAa,0BAA0B,YAGX;CAC1B,MAAM,EAAE,UAAU,kBAAkB;CAGpC,MAAMC,aAA2B,EAAE;CAGnC,MAAM,qBAAqB,IAAI,KAAqB;CAGpD,MAAM,YAAY,IAAI,KAAa;CAGnC,MAAM,iBAAiB,IAAI,KAAqB;CAEhD,MAAM,qBAAqB,QAAwB;EACjD,MAAM,UAAU,mBAAmB,IAAI,IAAI,IAAI;AAC/C,qBAAmB,IAAI,KAAK,UAAU,EAAE;AACxC,SAAO;;CAGT,MAAM,oBAAoB,aAA6B;EACrD,IAAI,OAAO;EACX,IAAI,SAAS;AACb,SAAO,UAAU,IAAI,KAAK,EAAE;AAC1B;AACA,UAAO,GAAG,SAAS,GAAG;;AAExB,YAAU,IAAI,KAAK;AACnB,SAAO;;AAGT,QAAO;EACL,WAAW,EAAE,SAAS,MAAM,aAA0B;GACpD,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG;GACpC,MAAM,aAAa,kBAAkB,IAAI;GAEzC,MAAMC,QAAoB;IACxB,aAAa;IACb;IACA;IACD;AAED,cAAW,KAAK,MAAM;AAEtB,UAAO;IACL,SAAS;IACT,OAAO,WAAW,SAAS;IAC5B;;EAGH,UAAU,QAA2B;AAEnC,OAAI,OAAO,UAAU,WAAW,SAAS,GAAG;AAC1C,UAAM,IAAI,MAAM,iDAAiD,WAAW,SAAS,EAAE,QAAQ,OAAO,QAAQ;;AAEhH,cAAW,KAAK;;EAGlB,qBAIE;GACA,MAAM,WAAW,cAAc,WAAW;GAC1C,MAAM,UAAU,iBAAiB,SAAS;GAC1C,MAAM,aAAa,WAAW,WAAW;GAGzC,IAAIC;AACJ,OAAI,iBAAiB,YAAY;AAG/B,oBAAgB;;AAGlB,UAAO;IACL;IACA;IACA;IACD;;EAGH,mBAAmB,SAA8B;AAC/C,UAAO,kBAAkB,UAAU,QAAQ;;EAG7C,sBAAsB,OAAe,UAAwB;AAC3D,kBAAe,IAAI,OAAO,SAAS;;EAGrC,eAAuB;AACrB,UAAO,WAAW;;EAErB;;;;;AAMH,MAAa,gCAER;CACH,MAAM,qBAAqB,IAAI,KAAqB;AAEpD,QAAO,EACL,kBAAkB,KAAqB;EACrC,MAAM,UAAU,mBAAmB,IAAI,IAAI,IAAI;AAC/C,qBAAmB,IAAI,KAAK,UAAU,EAAE;AACxC,SAAO;IAEV;;;;;AAMH,MAAa,0BAER;CACH,MAAM,YAAY,IAAI,KAAa;AAEnC,QAAO,EACL,iBAAiB,UAA0B;EACzC,IAAI,OAAO;EACX,IAAI,SAAS;AACb,SAAO,UAAU,IAAI,KAAK,EAAE;AAC1B;AACA,UAAO,GAAG,SAAS,GAAG;;AAExB,YAAU,IAAI,KAAK;AACnB,SAAO;IAEV;;;;;AAMH,MAAa,gBAAgB,UAAyC;AACpE,QAAO,MAAM,KAAK,UAAU,MAAM,YAAY,CAAC,KAAK,IAAI"}
@@ -1,5 +1,5 @@
1
- const require_canonical_id = require('../canonical-id-BFcryTw5.cjs');
2
- require('../utils-CmLf7LU5.cjs');
1
+ const require_canonical_id = require('./canonical-id-BFcryTw5.cjs');
2
+ require('./utils-CmLf7LU5.cjs');
3
3
 
4
4
  exports.CanonicalIdSchema = require_canonical_id.CanonicalIdSchema;
5
5
  exports.buildAstPath = require_canonical_id.buildAstPath;
@@ -1,2 +1,2 @@
1
- import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "../index-BG7Aiges.cjs";
1
+ import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "./index-BG7Aiges.cjs";
2
2
  export { CanonicalId, CanonicalIdSchema, CanonicalPathTracker, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker };
@@ -1,2 +1,2 @@
1
- import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "../index-C4t2Wbzs.mjs";
1
+ import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "./index-C4t2Wbzs.mjs";
2
2
  export { CanonicalId, CanonicalIdSchema, CanonicalPathTracker, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker };
@@ -1,4 +1,4 @@
1
- import "../utils-DLEgAn7q.mjs";
2
- import { a as CanonicalIdSchema, i as createPathTracker, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, t as buildAstPath } from "../canonical-id-BFnyQGST.mjs";
1
+ import "./utils-DLEgAn7q.mjs";
2
+ import { a as CanonicalIdSchema, i as createPathTracker, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, t as buildAstPath } from "./canonical-id-BFnyQGST.mjs";
3
3
 
4
4
  export { CanonicalIdSchema, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker };
@@ -1 +1 @@
1
- {"version":3,"file":"index-DaAp2rNj.d.cts","names":[],"sources":["../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/id.ts","../src/portable/runtime.ts","../src/portable/spawn.ts"],"sourcesContent":[],"mappings":";;AAMA;;AAE4C,UAF3B,UAAA,CAE2B;EACpB,QAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAFE,OAEF,CAAA,MAAA,CAAA;EACe,SAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAFK,OAEL,CAAA,IAAA,CAAA;EAAjB,MAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EADE,OACF,CAAA,OAAA,CAAA;EACsB,IAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EADtB,OACsB,CAAA;IACc,KAAA,EAFnB,IAEmB;IAAO,IAAA,EAAA,MAAA;EAsBjD,CAAA,CAAA;EA4FA,MAAA,CAAA,OAAA,EAAa,MAAA,EAAA,OAAI,EAAA,MAAU,CAAA,EAnHC,OAmHD,CAAA,IAAA,CAAA;EAW3B,KAAA,CAAA,IAAA,EAAA,MAAA,EAAA,QAAyB,EAAA;;MA7HiB;;ACN9C,iBD4BI,gBAAA,CAAA,CC5BS,ED4BW,UC5BX;AAER,iBDsHD,aAAA,CAAA,CCrHoB,EDqHH,UCrHgB;AAUjD;AAqCA;AAWA;;iBDsEgB,yBAAA,CAAA;;;;AAnIhB;;AAE4C,KCFhC,aAAA,GDEgC,QAAA,GAAA,QAAA;AACpB,UCDP,cAAA,CDCO;EACe,IAAA,CAAA,OAAA,EAAA,MAAA,EAAA,SAAA,CAAA,ECDH,aDCG,CAAA,EAAA,MAAA;;AACK,iBCQ5B,oBAAA,CAAA,CDR4B,ECQJ,cDRI;AACc,iBC4C1C,iBAAA,CAAA,CD5C0C,EC4CrB,cD5CqB;;AAsB1D;AA4FA;AAWA;iBCtEgB,6BAAA,CAAA;;;;AD7DhB;;;;;;AAK4C,iBED5B,UAAA,CAAA,CFC4B,EAAA,MAAA;;;;AAL5C;;AAE4C,cGJ/B,OHI+B,EAAA;EACpB,SAAA,KAAA,EAAA,OAAA;EACe,SAAA,MAAA,EAAA,OAAA;EAAjB,SAAA,iBAAA,EAAA,OAAA;CACsB;;;AAuB5C;AA4FgB,iBGjHA,IHiHa,CAAA,CAAA,CAAI,CAAA,EAAA,EAAA,GAAA,GGjHC,CHiHS,CAAA,EAAA,GAAA,GGjHC,CHiHD;AAW3C;;;;ACnIY,iBEwBI,qBAAA,CAAA,CFxBS,EAAA,IAAA;;;;ADAzB;;AAE4C,UIF3B,YAAA,CJE2B;EACpB,GAAA,EAAA,MAAA,EAAA;EACe,GAAA,CAAA,EAAA,MAAA;EAAjB,GAAA,CAAA,EIDd,MJCc,CAAA,MAAA,EAAA,MAAA,CAAA;;AAEoC,UIAzC,WAAA,CJAyC;EAAO,MAAA,EAAA,MAAA;EAsBjD,MAAA,EAAA,MAAA;EA4FA,QAAA,EAAA,MAAa;AAW7B;iBIvHsB,KAAA,UAAe,eAAe,QAAQ"}
1
+ {"version":3,"file":"index-DaAp2rNj.d.cts","names":[],"sources":["../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/id.ts","../src/portable/runtime.ts","../src/portable/spawn.ts"],"sourcesContent":[],"mappings":";;AAMA;;AAE4C,UAF3B,UAAA,CAE2B;EACpB,QAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EAFE,OAEF,CAAA,MAAA,CAAA;EACe,SAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAFK,OAEL,CAAA,IAAA,CAAA;EAAjB,MAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EADE,OACF,CAAA,OAAA,CAAA;EACsB,IAAA,CAAA,IAAA,EAAA,MAAA,CAAA,EADtB,OACsB,CAAA;IACc,KAAA,EAFnB,IAEmB;IAAO,IAAA,EAAA,MAAA;EAsBjD,CAAA,CAAA;EA4FA,MAAA,CAAA,OAAA,EAAa,MAAA,EAAA,OAAI,EAAA,MAAU,CAAA,EAnHC,OAmHD,CAAA,IAAA,CAAA;EAW3B,KAAA,CAAA,IAAA,EAAA,MAAA,EAAA,QAAyB,EAAA;;MA7HiB;;ACN9C,iBD4BI,gBAAA,CAAA,CC5BS,ED4BW,UC5BX;AAER,iBDsHD,aAAA,CAAA,CCrHoB,EDqHH,UCrHgB;AAUjD;AAqCA;AAWA;;iBDsEgB,yBAAA,CAAA;;;;AAnIhB;;AAE4C,KCFhC,aAAA,GDEgC,QAAA,GAAA,QAAA;AACpB,UCDP,cAAA,CDCO;EACe,IAAA,CAAA,OAAA,EAAA,MAAA,EAAA,SAAA,CAAA,ECDH,aDCG,CAAA,EAAA,MAAA;;AACK,iBCQ5B,oBAAA,CAAA,CDR4B,ECQJ,cDRI;AACc,iBC4C1C,iBAAA,CAAA,CD5C0C,EC4CrB,cD5CqB;;AAsB1D;AA4FA;AAWA;iBCtEgB,6BAAA,CAAA;;;;AD7DhB;;;;;;AAK4C,iBED5B,UAAA,CAAA,CFC4B,EAAA,MAAA;;;;AAL5C;;AAE4C,cGJ/B,OHI+B,EAAA;EACpB,SAAA,KAAA,EAAA,OAAA;EACe,SAAA,MAAA,EAAA,OAAA;EAAjB,SAAA,iBAAA,EAAA,OAAA;CACsB;;;AAuB5C;AA4FgB,iBGjHA,IHiHa,CAAA,CAAA,CAAA,CAAI,EAAA,EAAA,GAAA,GGjHC,CHiHS,CAAA,EAAA,GAAA,GGjHC,CHiHD;AAW3C;;;;ACnIY,iBEwBI,qBAAA,CAAA,CFxBS,EAAA,IAAA;;;;ADAzB;;AAE4C,UIF3B,YAAA,CJE2B;EACpB,GAAA,EAAA,MAAA,EAAA;EACe,GAAA,CAAA,EAAA,MAAA;EAAjB,GAAA,CAAA,EIDd,MJCc,CAAA,MAAA,EAAA,MAAA,CAAA;;AAEoC,UIAzC,WAAA,CJAyC;EAAO,MAAA,EAAA,MAAA;EAsBjD,MAAA,EAAA,MAAA;EA4FA,QAAA,EAAA,MAAa;AAW7B;iBIvHsB,KAAA,UAAe,eAAe,QAAQ"}
package/dist/index.cjs CHANGED
@@ -2,19 +2,282 @@ const require_canonical_id = require('./canonical-id-BFcryTw5.cjs');
2
2
  const require_utils = require('./utils-CmLf7LU5.cjs');
3
3
  const require_portable = require('./portable-C_7gJWmz.cjs');
4
4
  const require_zod = require('./zod-CynYgOoN.cjs');
5
+ let neverthrow = require("neverthrow");
5
6
 
7
+ //#region packages/common/src/scheduler/types.ts
8
+ /**
9
+ * Abstract base class for all effects.
10
+ * Effects encapsulate both the data and the execution logic.
11
+ *
12
+ * @template TResult - The type of value this effect produces when executed
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * function* myGenerator() {
17
+ * const value = yield* new PureEffect(42).run();
18
+ * return value; // 42
19
+ * }
20
+ * ```
21
+ */
22
+ var Effect = class {
23
+ /**
24
+ * Execute the effect synchronously and return the result.
25
+ */
26
+ executeSync() {
27
+ return this._executeSync();
28
+ }
29
+ /**
30
+ * Execute the effect asynchronously and return the result.
31
+ */
32
+ async executeAsync() {
33
+ return this._executeAsync();
34
+ }
35
+ /**
36
+ * Returns a generator that yields this effect and returns the result.
37
+ * Enables the `yield*` pattern for cleaner effect handling.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const value = yield* effect.run();
42
+ * ```
43
+ */
44
+ *run() {
45
+ return EffectReturn.unwrap(yield this);
46
+ }
47
+ };
48
+ const EFFECT_RETURN = Symbol("EffectReturn");
49
+ var EffectReturn = class EffectReturn {
50
+ [EFFECT_RETURN];
51
+ constructor(value) {
52
+ this[EFFECT_RETURN] = value;
53
+ }
54
+ static wrap(value) {
55
+ return new EffectReturn(value);
56
+ }
57
+ static unwrap(value) {
58
+ return value[EFFECT_RETURN];
59
+ }
60
+ };
61
+ /**
62
+ * Create a SchedulerError.
63
+ */
64
+ const createSchedulerError = (message, cause) => ({
65
+ kind: "scheduler-error",
66
+ message,
67
+ cause
68
+ });
69
+
70
+ //#endregion
71
+ //#region packages/common/src/scheduler/async-scheduler.ts
72
+ /**
73
+ * Create an asynchronous scheduler.
74
+ *
75
+ * This scheduler can handle all effect types including defer and yield.
76
+ * Parallel effects are executed concurrently using Promise.all.
77
+ *
78
+ * @returns An AsyncScheduler instance
79
+ *
80
+ * @example
81
+ * const scheduler = createAsyncScheduler();
82
+ * const result = await scheduler.run(function* () {
83
+ * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();
84
+ * yield* new YieldEffect().run(); // Yield to event loop
85
+ * return data;
86
+ * });
87
+ */
88
+ const createAsyncScheduler = () => {
89
+ const run = async (generatorFn) => {
90
+ try {
91
+ const generator = generatorFn();
92
+ let result = generator.next();
93
+ while (!result.done) {
94
+ const effect = result.value;
95
+ const effectResult = await effect.executeAsync();
96
+ result = generator.next(EffectReturn.wrap(effectResult));
97
+ }
98
+ return (0, neverthrow.ok)(result.value);
99
+ } catch (error) {
100
+ if (isSchedulerError$1(error)) {
101
+ return (0, neverthrow.err)(error);
102
+ }
103
+ return (0, neverthrow.err)(createSchedulerError(error instanceof Error ? error.message : String(error), error));
104
+ }
105
+ };
106
+ return { run };
107
+ };
108
+ /**
109
+ * Type guard for SchedulerError.
110
+ */
111
+ const isSchedulerError$1 = (error) => {
112
+ return typeof error === "object" && error !== null && error.kind === "scheduler-error";
113
+ };
114
+
115
+ //#endregion
116
+ //#region packages/common/src/scheduler/effect.ts
117
+ /**
118
+ * Pure effect - returns a value immediately.
119
+ * Works in both sync and async schedulers.
120
+ *
121
+ * @example
122
+ * const result = yield* new PureEffect(42).run(); // 42
123
+ */
124
+ var PureEffect = class extends Effect {
125
+ constructor(pureValue) {
126
+ super();
127
+ this.pureValue = pureValue;
128
+ }
129
+ _executeSync() {
130
+ return this.pureValue;
131
+ }
132
+ _executeAsync() {
133
+ return Promise.resolve(this.pureValue);
134
+ }
135
+ };
136
+ /**
137
+ * Defer effect - wraps a Promise for async execution.
138
+ * Only works in async schedulers; throws in sync schedulers.
139
+ *
140
+ * @example
141
+ * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();
142
+ */
143
+ var DeferEffect = class extends Effect {
144
+ constructor(promise) {
145
+ super();
146
+ this.promise = promise;
147
+ }
148
+ _executeSync() {
149
+ throw new Error("DeferEffect is not supported in sync scheduler. Use AsyncScheduler instead.");
150
+ }
151
+ _executeAsync() {
152
+ return this.promise;
153
+ }
154
+ };
155
+ /**
156
+ * Parallel effect - executes multiple effects concurrently.
157
+ * In sync schedulers, effects are executed sequentially.
158
+ * In async schedulers, effects are executed with Promise.all.
159
+ *
160
+ * @example
161
+ * const results = yield* new ParallelEffect([new PureEffect(1), new PureEffect(2)]).run(); // [1, 2]
162
+ */
163
+ var ParallelEffect = class extends Effect {
164
+ constructor(effects) {
165
+ super();
166
+ this.effects = effects;
167
+ }
168
+ _executeSync() {
169
+ return this.effects.map((e) => e.executeSync());
170
+ }
171
+ async _executeAsync() {
172
+ return Promise.all(this.effects.map((e) => e.executeAsync()));
173
+ }
174
+ };
175
+ /**
176
+ * Yield effect - yields control back to the event loop.
177
+ * This helps prevent blocking the event loop in long-running operations.
178
+ * Only works in async schedulers; throws in sync schedulers.
179
+ *
180
+ * @example
181
+ * for (let i = 0; i < 10000; i++) {
182
+ * doWork(i);
183
+ * if (i % 100 === 0) {
184
+ * yield* new YieldEffect().run();
185
+ * }
186
+ * }
187
+ */
188
+ var YieldEffect = class extends Effect {
189
+ _executeSync() {
190
+ throw new Error("YieldEffect is not supported in sync scheduler. Use AsyncScheduler instead.");
191
+ }
192
+ async _executeAsync() {
193
+ await new Promise((resolve) => {
194
+ if (typeof setImmediate !== "undefined") {
195
+ setImmediate(resolve);
196
+ } else {
197
+ setTimeout(resolve, 0);
198
+ }
199
+ });
200
+ }
201
+ };
202
+ /**
203
+ * Effect factory namespace for convenience.
204
+ * Provides static methods to create effects.
205
+ */
206
+ const Effects = {
207
+ pure: (value) => new PureEffect(value),
208
+ defer: (promise) => new DeferEffect(promise),
209
+ parallel: (effects) => new ParallelEffect(effects),
210
+ yield: () => new YieldEffect()
211
+ };
212
+
213
+ //#endregion
214
+ //#region packages/common/src/scheduler/sync-scheduler.ts
215
+ /**
216
+ * Create a synchronous scheduler.
217
+ *
218
+ * This scheduler executes generators synchronously.
219
+ * It throws an error if an async-only effect (defer, yield) is encountered.
220
+ *
221
+ * @returns A SyncScheduler instance
222
+ *
223
+ * @example
224
+ * const scheduler = createSyncScheduler();
225
+ * const result = scheduler.run(function* () {
226
+ * const a = yield* new PureEffect(1).run();
227
+ * const b = yield* new PureEffect(2).run();
228
+ * return a + b;
229
+ * });
230
+ * // result = ok(3)
231
+ */
232
+ const createSyncScheduler = () => {
233
+ const run = (generatorFn) => {
234
+ try {
235
+ const generator = generatorFn();
236
+ let result = generator.next();
237
+ while (!result.done) {
238
+ const effect = result.value;
239
+ const effectResult = effect.executeSync();
240
+ result = generator.next(EffectReturn.wrap(effectResult));
241
+ }
242
+ return (0, neverthrow.ok)(result.value);
243
+ } catch (error) {
244
+ if (isSchedulerError(error)) {
245
+ return (0, neverthrow.err)(error);
246
+ }
247
+ return (0, neverthrow.err)(createSchedulerError(error instanceof Error ? error.message : String(error), error));
248
+ }
249
+ };
250
+ return { run };
251
+ };
252
+ /**
253
+ * Type guard for SchedulerError.
254
+ */
255
+ const isSchedulerError = (error) => {
256
+ return typeof error === "object" && error !== null && error.kind === "scheduler-error";
257
+ };
258
+
259
+ //#endregion
6
260
  exports.CanonicalIdSchema = require_canonical_id.CanonicalIdSchema;
261
+ exports.DeferEffect = DeferEffect;
262
+ exports.Effect = Effect;
263
+ exports.Effects = Effects;
7
264
  exports.MODULE_EXTENSION_CANDIDATES = require_utils.MODULE_EXTENSION_CANDIDATES;
265
+ exports.ParallelEffect = ParallelEffect;
266
+ exports.PureEffect = PureEffect;
267
+ exports.YieldEffect = YieldEffect;
8
268
  exports.__resetPortableFSForTests = require_portable.__resetPortableFSForTests;
9
269
  exports.__resetPortableHasherForTests = require_portable.__resetPortableHasherForTests;
10
270
  exports.buildAstPath = require_canonical_id.buildAstPath;
11
271
  exports.cachedFn = require_utils.cachedFn;
272
+ exports.createAsyncScheduler = createAsyncScheduler;
12
273
  exports.createCanonicalId = require_canonical_id.createCanonicalId;
13
274
  exports.createCanonicalTracker = require_canonical_id.createCanonicalTracker;
14
275
  exports.createOccurrenceTracker = require_canonical_id.createOccurrenceTracker;
15
276
  exports.createPathTracker = require_canonical_id.createPathTracker;
16
277
  exports.createPortableFS = require_portable.createPortableFS;
17
278
  exports.createPortableHasher = require_portable.createPortableHasher;
279
+ exports.createSchedulerError = createSchedulerError;
280
+ exports.createSyncScheduler = createSyncScheduler;
18
281
  exports.defineSchemaFor = require_zod.defineSchemaFor;
19
282
  exports.generateId = require_portable.generateId;
20
283
  exports.getPortableFS = require_portable.getPortableFS;
@@ -27,4 +290,5 @@ exports.resetPortableForTests = require_portable.resetPortableForTests;
27
290
  exports.resolveRelativeImportWithExistenceCheck = require_utils.resolveRelativeImportWithExistenceCheck;
28
291
  exports.resolveRelativeImportWithReferences = require_utils.resolveRelativeImportWithReferences;
29
292
  exports.runtime = require_portable.runtime;
30
- exports.spawn = require_portable.spawn;
293
+ exports.spawn = require_portable.spawn;
294
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["isSchedulerError","pureValue: T","promise: Promise<T>","effects: readonly Effect<unknown>[]"],"sources":["../src/scheduler/types.ts","../src/scheduler/async-scheduler.ts","../src/scheduler/effect.ts","../src/scheduler/sync-scheduler.ts"],"sourcesContent":["import type { Result } from \"neverthrow\";\n\n/**\n * Abstract base class for all effects.\n * Effects encapsulate both the data and the execution logic.\n *\n * @template TResult - The type of value this effect produces when executed\n *\n * @example\n * ```typescript\n * function* myGenerator() {\n * const value = yield* new PureEffect(42).run();\n * return value; // 42\n * }\n * ```\n */\nexport abstract class Effect<TResult = unknown> {\n /**\n * Execute the effect synchronously and return the result.\n */\n executeSync(): TResult {\n return this._executeSync();\n }\n\n /**\n * Execute the effect asynchronously and return the result.\n */\n async executeAsync(): Promise<TResult> {\n return this._executeAsync();\n }\n\n /**\n * Returns a generator that yields this effect and returns the result.\n * Enables the `yield*` pattern for cleaner effect handling.\n *\n * @example\n * ```typescript\n * const value = yield* effect.run();\n * ```\n */\n *run(): Generator<Effect<TResult>, TResult, EffectReturn> {\n return EffectReturn.unwrap((yield this) as EffectReturn<TResult>);\n }\n\n /**\n * Internal synchronous execution logic.\n * Subclasses must implement this method.\n */\n protected abstract _executeSync(): TResult;\n\n /**\n * Internal asynchronous execution logic.\n * Subclasses must implement this method.\n */\n protected abstract _executeAsync(): Promise<TResult>;\n}\n\nconst EFFECT_RETURN = Symbol(\"EffectReturn\");\nexport class EffectReturn<TResult = unknown> {\n private readonly [EFFECT_RETURN]: TResult;\n\n private constructor(value: TResult) {\n this[EFFECT_RETURN] = value;\n }\n\n static wrap<TResult>(value: TResult): EffectReturn<TResult> {\n return new EffectReturn(value);\n }\n\n static unwrap<TResult>(value: EffectReturn<TResult>): TResult {\n return value[EFFECT_RETURN];\n }\n}\n\n/**\n * Extract the result type from an Effect.\n */\nexport type EffectResult<E> = E extends Effect<infer T> ? T : never;\n\n/**\n * Generator type that yields Effects.\n */\nexport type EffectGenerator<TReturn> = Generator<Effect, TReturn, EffectReturn>;\n\n/**\n * Generator function type that creates an EffectGenerator.\n */\nexport type EffectGeneratorFn<TReturn> = () => EffectGenerator<TReturn>;\n\n/**\n * Error type for scheduler operations.\n */\nexport type SchedulerError = {\n readonly kind: \"scheduler-error\";\n readonly message: string;\n readonly cause?: unknown;\n};\n\n/**\n * Create a SchedulerError.\n */\nexport const createSchedulerError = (message: string, cause?: unknown): SchedulerError => ({\n kind: \"scheduler-error\",\n message,\n cause,\n});\n\n/**\n * Synchronous scheduler interface.\n * Throws if an async-only effect (defer, yield) is encountered.\n */\nexport interface SyncScheduler {\n run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError>;\n}\n\n/**\n * Asynchronous scheduler interface.\n * Handles all effect types including defer, yield, and parallel.\n */\nexport interface AsyncScheduler {\n run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>>;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AsyncScheduler, Effect, EffectGeneratorFn, SchedulerError } from \"./types\";\nimport { createSchedulerError, EffectReturn } from \"./types\";\n\n/**\n * Create an asynchronous scheduler.\n *\n * This scheduler can handle all effect types including defer and yield.\n * Parallel effects are executed concurrently using Promise.all.\n *\n * @returns An AsyncScheduler instance\n *\n * @example\n * const scheduler = createAsyncScheduler();\n * const result = await scheduler.run(function* () {\n * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();\n * yield* new YieldEffect().run(); // Yield to event loop\n * return data;\n * });\n */\nexport const createAsyncScheduler = (): AsyncScheduler => {\n const run = async <TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>> => {\n try {\n const generator = generatorFn();\n let result = generator.next();\n\n while (!result.done) {\n const effect = result.value as Effect<unknown>;\n const effectResult = await effect.executeAsync();\n result = generator.next(EffectReturn.wrap(effectResult));\n }\n\n return ok(result.value);\n } catch (error) {\n if (isSchedulerError(error)) {\n return err(error);\n }\n return err(createSchedulerError(error instanceof Error ? error.message : String(error), error));\n }\n };\n\n return { run };\n};\n\n/**\n * Type guard for SchedulerError.\n */\nconst isSchedulerError = (error: unknown): error is SchedulerError => {\n return typeof error === \"object\" && error !== null && (error as SchedulerError).kind === \"scheduler-error\";\n};\n","import { Effect } from \"./types\";\n\n/**\n * Pure effect - returns a value immediately.\n * Works in both sync and async schedulers.\n *\n * @example\n * const result = yield* new PureEffect(42).run(); // 42\n */\nexport class PureEffect<T> extends Effect<T> {\n constructor(readonly pureValue: T) {\n super();\n }\n\n protected _executeSync(): T {\n return this.pureValue;\n }\n\n protected _executeAsync(): Promise<T> {\n return Promise.resolve(this.pureValue);\n }\n}\n\n/**\n * Defer effect - wraps a Promise for async execution.\n * Only works in async schedulers; throws in sync schedulers.\n *\n * @example\n * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();\n */\nexport class DeferEffect<T> extends Effect<T> {\n constructor(readonly promise: Promise<T>) {\n super();\n }\n\n protected _executeSync(): T {\n throw new Error(\"DeferEffect is not supported in sync scheduler. Use AsyncScheduler instead.\");\n }\n\n protected _executeAsync(): Promise<T> {\n return this.promise;\n }\n}\n\n/**\n * Parallel effect - executes multiple effects concurrently.\n * In sync schedulers, effects are executed sequentially.\n * In async schedulers, effects are executed with Promise.all.\n *\n * @example\n * const results = yield* new ParallelEffect([new PureEffect(1), new PureEffect(2)]).run(); // [1, 2]\n */\nexport class ParallelEffect extends Effect<readonly unknown[]> {\n constructor(readonly effects: readonly Effect<unknown>[]) {\n super();\n }\n\n protected _executeSync(): readonly unknown[] {\n return this.effects.map((e) => e.executeSync());\n }\n\n protected async _executeAsync(): Promise<readonly unknown[]> {\n return Promise.all(this.effects.map((e) => e.executeAsync()));\n }\n}\n\n/**\n * Yield effect - yields control back to the event loop.\n * This helps prevent blocking the event loop in long-running operations.\n * Only works in async schedulers; throws in sync schedulers.\n *\n * @example\n * for (let i = 0; i < 10000; i++) {\n * doWork(i);\n * if (i % 100 === 0) {\n * yield* new YieldEffect().run();\n * }\n * }\n */\nexport class YieldEffect extends Effect<void> {\n protected _executeSync(): void {\n throw new Error(\"YieldEffect is not supported in sync scheduler. Use AsyncScheduler instead.\");\n }\n\n protected async _executeAsync(): Promise<void> {\n await new Promise<void>((resolve) => {\n if (typeof setImmediate !== \"undefined\") {\n setImmediate(resolve);\n } else {\n setTimeout(resolve, 0);\n }\n });\n }\n}\n\n/**\n * Effect factory namespace for convenience.\n * Provides static methods to create effects.\n */\nexport const Effects = {\n /**\n * Create a pure effect that returns a value immediately.\n */\n pure: <T>(value: T): PureEffect<T> => new PureEffect(value),\n\n /**\n * Create a defer effect that wraps a Promise.\n */\n defer: <T>(promise: Promise<T>): DeferEffect<T> => new DeferEffect(promise),\n\n /**\n * Create a parallel effect that executes multiple effects concurrently.\n */\n parallel: (effects: readonly Effect<unknown>[]): ParallelEffect => new ParallelEffect(effects),\n\n /**\n * Create a yield effect that returns control to the event loop.\n */\n yield: (): YieldEffect => new YieldEffect(),\n} as const;\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { Effect, EffectGeneratorFn, SchedulerError, SyncScheduler } from \"./types\";\nimport { createSchedulerError, EffectReturn } from \"./types\";\n\n/**\n * Create a synchronous scheduler.\n *\n * This scheduler executes generators synchronously.\n * It throws an error if an async-only effect (defer, yield) is encountered.\n *\n * @returns A SyncScheduler instance\n *\n * @example\n * const scheduler = createSyncScheduler();\n * const result = scheduler.run(function* () {\n * const a = yield* new PureEffect(1).run();\n * const b = yield* new PureEffect(2).run();\n * return a + b;\n * });\n * // result = ok(3)\n */\nexport const createSyncScheduler = (): SyncScheduler => {\n const run = <TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError> => {\n try {\n const generator = generatorFn();\n let result = generator.next();\n\n while (!result.done) {\n const effect = result.value as Effect<unknown>;\n const effectResult = effect.executeSync();\n result = generator.next(EffectReturn.wrap(effectResult));\n }\n\n return ok(result.value);\n } catch (error) {\n if (isSchedulerError(error)) {\n return err(error);\n }\n return err(createSchedulerError(error instanceof Error ? error.message : String(error), error));\n }\n };\n\n return { run };\n};\n\n/**\n * Type guard for SchedulerError.\n */\nconst isSchedulerError = (error: unknown): error is SchedulerError => {\n return typeof error === \"object\" && error !== null && (error as SchedulerError).kind === \"scheduler-error\";\n};\n"],"mappings":"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"}