@soda-gql/common 0.0.8 → 0.1.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/README.md +121 -0
- package/dist/index.cjs +263 -0
- package/dist/index.d.cts +216 -1
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +216 -1
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +256 -1
- package/dist/index.mjs.map +1 -0
- package/package.json +9 -6
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# @soda-gql/common
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@soda-gql/common)
|
|
4
|
+
[](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
|
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;
|
package/dist/index.d.cts
CHANGED
|
@@ -2,4 +2,219 @@ import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as
|
|
|
2
2
|
import { a as resetPortableForTests, c as HashAlgorithm, d as createPortableHasher, f as getPortableHasher, g as getPortableFS, h as createPortableFS, i as once, l as PortableHasher, m as __resetPortableFSForTests, n as SpawnResult, o as runtime, p as PortableFS, r as spawn, s as generateId, t as SpawnOptions, u as __resetPortableHasherForTests } from "./index-DaAp2rNj.cjs";
|
|
3
3
|
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "./index-LaXfl_e_.cjs";
|
|
4
4
|
import { n as ShapeFor, r as defineSchemaFor, t as SchemaFor } from "./index-LHYortIn.cjs";
|
|
5
|
-
|
|
5
|
+
import { Result } from "neverthrow";
|
|
6
|
+
|
|
7
|
+
//#region packages/common/src/scheduler/types.d.ts
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for all effects.
|
|
11
|
+
* Effects encapsulate both the data and the execution logic.
|
|
12
|
+
*
|
|
13
|
+
* @template TResult - The type of value this effect produces when executed
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* function* myGenerator() {
|
|
18
|
+
* const value = yield* new PureEffect(42).run();
|
|
19
|
+
* return value; // 42
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare abstract class Effect<TResult = unknown> {
|
|
24
|
+
/**
|
|
25
|
+
* Execute the effect synchronously and return the result.
|
|
26
|
+
*/
|
|
27
|
+
executeSync(): TResult;
|
|
28
|
+
/**
|
|
29
|
+
* Execute the effect asynchronously and return the result.
|
|
30
|
+
*/
|
|
31
|
+
executeAsync(): Promise<TResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Returns a generator that yields this effect and returns the result.
|
|
34
|
+
* Enables the `yield*` pattern for cleaner effect handling.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const value = yield* effect.run();
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
run(): Generator<Effect<TResult>, TResult, EffectReturn>;
|
|
42
|
+
/**
|
|
43
|
+
* Internal synchronous execution logic.
|
|
44
|
+
* Subclasses must implement this method.
|
|
45
|
+
*/
|
|
46
|
+
protected abstract _executeSync(): TResult;
|
|
47
|
+
/**
|
|
48
|
+
* Internal asynchronous execution logic.
|
|
49
|
+
* Subclasses must implement this method.
|
|
50
|
+
*/
|
|
51
|
+
protected abstract _executeAsync(): Promise<TResult>;
|
|
52
|
+
}
|
|
53
|
+
declare const EFFECT_RETURN: unique symbol;
|
|
54
|
+
declare class EffectReturn<TResult = unknown> {
|
|
55
|
+
private readonly [EFFECT_RETURN];
|
|
56
|
+
private constructor();
|
|
57
|
+
static wrap<TResult>(value: TResult): EffectReturn<TResult>;
|
|
58
|
+
static unwrap<TResult>(value: EffectReturn<TResult>): TResult;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extract the result type from an Effect.
|
|
62
|
+
*/
|
|
63
|
+
type EffectResult<E> = E extends Effect<infer T> ? T : never;
|
|
64
|
+
/**
|
|
65
|
+
* Generator type that yields Effects.
|
|
66
|
+
*/
|
|
67
|
+
type EffectGenerator<TReturn> = Generator<Effect, TReturn, EffectReturn>;
|
|
68
|
+
/**
|
|
69
|
+
* Generator function type that creates an EffectGenerator.
|
|
70
|
+
*/
|
|
71
|
+
type EffectGeneratorFn<TReturn> = () => EffectGenerator<TReturn>;
|
|
72
|
+
/**
|
|
73
|
+
* Error type for scheduler operations.
|
|
74
|
+
*/
|
|
75
|
+
type SchedulerError = {
|
|
76
|
+
readonly kind: "scheduler-error";
|
|
77
|
+
readonly message: string;
|
|
78
|
+
readonly cause?: unknown;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Create a SchedulerError.
|
|
82
|
+
*/
|
|
83
|
+
declare const createSchedulerError: (message: string, cause?: unknown) => SchedulerError;
|
|
84
|
+
/**
|
|
85
|
+
* Synchronous scheduler interface.
|
|
86
|
+
* Throws if an async-only effect (defer, yield) is encountered.
|
|
87
|
+
*/
|
|
88
|
+
interface SyncScheduler {
|
|
89
|
+
run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Asynchronous scheduler interface.
|
|
93
|
+
* Handles all effect types including defer, yield, and parallel.
|
|
94
|
+
*/
|
|
95
|
+
interface AsyncScheduler {
|
|
96
|
+
run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>>;
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region packages/common/src/scheduler/async-scheduler.d.ts
|
|
100
|
+
/**
|
|
101
|
+
* Create an asynchronous scheduler.
|
|
102
|
+
*
|
|
103
|
+
* This scheduler can handle all effect types including defer and yield.
|
|
104
|
+
* Parallel effects are executed concurrently using Promise.all.
|
|
105
|
+
*
|
|
106
|
+
* @returns An AsyncScheduler instance
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* const scheduler = createAsyncScheduler();
|
|
110
|
+
* const result = await scheduler.run(function* () {
|
|
111
|
+
* const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();
|
|
112
|
+
* yield* new YieldEffect().run(); // Yield to event loop
|
|
113
|
+
* return data;
|
|
114
|
+
* });
|
|
115
|
+
*/
|
|
116
|
+
declare const createAsyncScheduler: () => AsyncScheduler;
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region packages/common/src/scheduler/effect.d.ts
|
|
119
|
+
/**
|
|
120
|
+
* Pure effect - returns a value immediately.
|
|
121
|
+
* Works in both sync and async schedulers.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const result = yield* new PureEffect(42).run(); // 42
|
|
125
|
+
*/
|
|
126
|
+
declare class PureEffect<T> extends Effect<T> {
|
|
127
|
+
readonly pureValue: T;
|
|
128
|
+
constructor(pureValue: T);
|
|
129
|
+
protected _executeSync(): T;
|
|
130
|
+
protected _executeAsync(): Promise<T>;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Defer effect - wraps a Promise for async execution.
|
|
134
|
+
* Only works in async schedulers; throws in sync schedulers.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();
|
|
138
|
+
*/
|
|
139
|
+
declare class DeferEffect<T> extends Effect<T> {
|
|
140
|
+
readonly promise: Promise<T>;
|
|
141
|
+
constructor(promise: Promise<T>);
|
|
142
|
+
protected _executeSync(): T;
|
|
143
|
+
protected _executeAsync(): Promise<T>;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parallel effect - executes multiple effects concurrently.
|
|
147
|
+
* In sync schedulers, effects are executed sequentially.
|
|
148
|
+
* In async schedulers, effects are executed with Promise.all.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* const results = yield* new ParallelEffect([new PureEffect(1), new PureEffect(2)]).run(); // [1, 2]
|
|
152
|
+
*/
|
|
153
|
+
declare class ParallelEffect extends Effect<readonly unknown[]> {
|
|
154
|
+
readonly effects: readonly Effect<unknown>[];
|
|
155
|
+
constructor(effects: readonly Effect<unknown>[]);
|
|
156
|
+
protected _executeSync(): readonly unknown[];
|
|
157
|
+
protected _executeAsync(): Promise<readonly unknown[]>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Yield effect - yields control back to the event loop.
|
|
161
|
+
* This helps prevent blocking the event loop in long-running operations.
|
|
162
|
+
* Only works in async schedulers; throws in sync schedulers.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* for (let i = 0; i < 10000; i++) {
|
|
166
|
+
* doWork(i);
|
|
167
|
+
* if (i % 100 === 0) {
|
|
168
|
+
* yield* new YieldEffect().run();
|
|
169
|
+
* }
|
|
170
|
+
* }
|
|
171
|
+
*/
|
|
172
|
+
declare class YieldEffect extends Effect<void> {
|
|
173
|
+
protected _executeSync(): void;
|
|
174
|
+
protected _executeAsync(): Promise<void>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Effect factory namespace for convenience.
|
|
178
|
+
* Provides static methods to create effects.
|
|
179
|
+
*/
|
|
180
|
+
declare const Effects: {
|
|
181
|
+
/**
|
|
182
|
+
* Create a pure effect that returns a value immediately.
|
|
183
|
+
*/
|
|
184
|
+
readonly pure: <T>(value: T) => PureEffect<T>;
|
|
185
|
+
/**
|
|
186
|
+
* Create a defer effect that wraps a Promise.
|
|
187
|
+
*/
|
|
188
|
+
readonly defer: <T>(promise: Promise<T>) => DeferEffect<T>;
|
|
189
|
+
/**
|
|
190
|
+
* Create a parallel effect that executes multiple effects concurrently.
|
|
191
|
+
*/
|
|
192
|
+
readonly parallel: (effects: readonly Effect<unknown>[]) => ParallelEffect;
|
|
193
|
+
/**
|
|
194
|
+
* Create a yield effect that returns control to the event loop.
|
|
195
|
+
*/
|
|
196
|
+
readonly yield: () => YieldEffect;
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region packages/common/src/scheduler/sync-scheduler.d.ts
|
|
200
|
+
/**
|
|
201
|
+
* Create a synchronous scheduler.
|
|
202
|
+
*
|
|
203
|
+
* This scheduler executes generators synchronously.
|
|
204
|
+
* It throws an error if an async-only effect (defer, yield) is encountered.
|
|
205
|
+
*
|
|
206
|
+
* @returns A SyncScheduler instance
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* const scheduler = createSyncScheduler();
|
|
210
|
+
* const result = scheduler.run(function* () {
|
|
211
|
+
* const a = yield* new PureEffect(1).run();
|
|
212
|
+
* const b = yield* new PureEffect(2).run();
|
|
213
|
+
* return a + b;
|
|
214
|
+
* });
|
|
215
|
+
* // result = ok(3)
|
|
216
|
+
*/
|
|
217
|
+
declare const createSyncScheduler: () => SyncScheduler;
|
|
218
|
+
//#endregion
|
|
219
|
+
export { type AsyncScheduler, CanonicalId, CanonicalIdSchema, CanonicalPathTracker, DeferEffect, Effect, type EffectGenerator, type EffectGeneratorFn, type EffectResult, Effects, HashAlgorithm, MODULE_EXTENSION_CANDIDATES, ParallelEffect, PortableFS, PortableHasher, PureEffect, type SchedulerError, SchemaFor, ScopeFrame, ScopeHandle, ShapeFor, SpawnOptions, SpawnResult, type SyncScheduler, YieldEffect, __resetPortableFSForTests, __resetPortableHasherForTests, buildAstPath, cachedFn, createAsyncScheduler, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, createPortableFS, createPortableHasher, createSchedulerError, createSyncScheduler, defineSchemaFor, generateId, getPortableFS, getPortableHasher, isExternalSpecifier, isRelativeSpecifier, normalizePath, once, resetPortableForTests, resolveRelativeImportWithExistenceCheck, resolveRelativeImportWithReferences, runtime, spawn };
|
|
220
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/scheduler/types.ts","../src/scheduler/async-scheduler.ts","../src/scheduler/effect.ts","../src/scheduler/sync-scheduler.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -2,4 +2,219 @@ import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as
|
|
|
2
2
|
import { a as resetPortableForTests, c as HashAlgorithm, d as createPortableHasher, f as getPortableHasher, g as getPortableFS, h as createPortableFS, i as once, l as PortableHasher, m as __resetPortableFSForTests, n as SpawnResult, o as runtime, p as PortableFS, r as spawn, s as generateId, t as SpawnOptions, u as __resetPortableHasherForTests } from "./index-BedBpKbv.mjs";
|
|
3
3
|
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "./index-Dv8spPt0.mjs";
|
|
4
4
|
import { n as ShapeFor, r as defineSchemaFor, t as SchemaFor } from "./index-Dit86qkX.mjs";
|
|
5
|
-
|
|
5
|
+
import { Result } from "neverthrow";
|
|
6
|
+
|
|
7
|
+
//#region packages/common/src/scheduler/types.d.ts
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for all effects.
|
|
11
|
+
* Effects encapsulate both the data and the execution logic.
|
|
12
|
+
*
|
|
13
|
+
* @template TResult - The type of value this effect produces when executed
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* function* myGenerator() {
|
|
18
|
+
* const value = yield* new PureEffect(42).run();
|
|
19
|
+
* return value; // 42
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare abstract class Effect<TResult = unknown> {
|
|
24
|
+
/**
|
|
25
|
+
* Execute the effect synchronously and return the result.
|
|
26
|
+
*/
|
|
27
|
+
executeSync(): TResult;
|
|
28
|
+
/**
|
|
29
|
+
* Execute the effect asynchronously and return the result.
|
|
30
|
+
*/
|
|
31
|
+
executeAsync(): Promise<TResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Returns a generator that yields this effect and returns the result.
|
|
34
|
+
* Enables the `yield*` pattern for cleaner effect handling.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const value = yield* effect.run();
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
run(): Generator<Effect<TResult>, TResult, EffectReturn>;
|
|
42
|
+
/**
|
|
43
|
+
* Internal synchronous execution logic.
|
|
44
|
+
* Subclasses must implement this method.
|
|
45
|
+
*/
|
|
46
|
+
protected abstract _executeSync(): TResult;
|
|
47
|
+
/**
|
|
48
|
+
* Internal asynchronous execution logic.
|
|
49
|
+
* Subclasses must implement this method.
|
|
50
|
+
*/
|
|
51
|
+
protected abstract _executeAsync(): Promise<TResult>;
|
|
52
|
+
}
|
|
53
|
+
declare const EFFECT_RETURN: unique symbol;
|
|
54
|
+
declare class EffectReturn<TResult = unknown> {
|
|
55
|
+
private readonly [EFFECT_RETURN];
|
|
56
|
+
private constructor();
|
|
57
|
+
static wrap<TResult>(value: TResult): EffectReturn<TResult>;
|
|
58
|
+
static unwrap<TResult>(value: EffectReturn<TResult>): TResult;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extract the result type from an Effect.
|
|
62
|
+
*/
|
|
63
|
+
type EffectResult<E> = E extends Effect<infer T> ? T : never;
|
|
64
|
+
/**
|
|
65
|
+
* Generator type that yields Effects.
|
|
66
|
+
*/
|
|
67
|
+
type EffectGenerator<TReturn> = Generator<Effect, TReturn, EffectReturn>;
|
|
68
|
+
/**
|
|
69
|
+
* Generator function type that creates an EffectGenerator.
|
|
70
|
+
*/
|
|
71
|
+
type EffectGeneratorFn<TReturn> = () => EffectGenerator<TReturn>;
|
|
72
|
+
/**
|
|
73
|
+
* Error type for scheduler operations.
|
|
74
|
+
*/
|
|
75
|
+
type SchedulerError = {
|
|
76
|
+
readonly kind: "scheduler-error";
|
|
77
|
+
readonly message: string;
|
|
78
|
+
readonly cause?: unknown;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Create a SchedulerError.
|
|
82
|
+
*/
|
|
83
|
+
declare const createSchedulerError: (message: string, cause?: unknown) => SchedulerError;
|
|
84
|
+
/**
|
|
85
|
+
* Synchronous scheduler interface.
|
|
86
|
+
* Throws if an async-only effect (defer, yield) is encountered.
|
|
87
|
+
*/
|
|
88
|
+
interface SyncScheduler {
|
|
89
|
+
run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Asynchronous scheduler interface.
|
|
93
|
+
* Handles all effect types including defer, yield, and parallel.
|
|
94
|
+
*/
|
|
95
|
+
interface AsyncScheduler {
|
|
96
|
+
run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>>;
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region packages/common/src/scheduler/async-scheduler.d.ts
|
|
100
|
+
/**
|
|
101
|
+
* Create an asynchronous scheduler.
|
|
102
|
+
*
|
|
103
|
+
* This scheduler can handle all effect types including defer and yield.
|
|
104
|
+
* Parallel effects are executed concurrently using Promise.all.
|
|
105
|
+
*
|
|
106
|
+
* @returns An AsyncScheduler instance
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* const scheduler = createAsyncScheduler();
|
|
110
|
+
* const result = await scheduler.run(function* () {
|
|
111
|
+
* const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();
|
|
112
|
+
* yield* new YieldEffect().run(); // Yield to event loop
|
|
113
|
+
* return data;
|
|
114
|
+
* });
|
|
115
|
+
*/
|
|
116
|
+
declare const createAsyncScheduler: () => AsyncScheduler;
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region packages/common/src/scheduler/effect.d.ts
|
|
119
|
+
/**
|
|
120
|
+
* Pure effect - returns a value immediately.
|
|
121
|
+
* Works in both sync and async schedulers.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const result = yield* new PureEffect(42).run(); // 42
|
|
125
|
+
*/
|
|
126
|
+
declare class PureEffect<T> extends Effect<T> {
|
|
127
|
+
readonly pureValue: T;
|
|
128
|
+
constructor(pureValue: T);
|
|
129
|
+
protected _executeSync(): T;
|
|
130
|
+
protected _executeAsync(): Promise<T>;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Defer effect - wraps a Promise for async execution.
|
|
134
|
+
* Only works in async schedulers; throws in sync schedulers.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();
|
|
138
|
+
*/
|
|
139
|
+
declare class DeferEffect<T> extends Effect<T> {
|
|
140
|
+
readonly promise: Promise<T>;
|
|
141
|
+
constructor(promise: Promise<T>);
|
|
142
|
+
protected _executeSync(): T;
|
|
143
|
+
protected _executeAsync(): Promise<T>;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parallel effect - executes multiple effects concurrently.
|
|
147
|
+
* In sync schedulers, effects are executed sequentially.
|
|
148
|
+
* In async schedulers, effects are executed with Promise.all.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* const results = yield* new ParallelEffect([new PureEffect(1), new PureEffect(2)]).run(); // [1, 2]
|
|
152
|
+
*/
|
|
153
|
+
declare class ParallelEffect extends Effect<readonly unknown[]> {
|
|
154
|
+
readonly effects: readonly Effect<unknown>[];
|
|
155
|
+
constructor(effects: readonly Effect<unknown>[]);
|
|
156
|
+
protected _executeSync(): readonly unknown[];
|
|
157
|
+
protected _executeAsync(): Promise<readonly unknown[]>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Yield effect - yields control back to the event loop.
|
|
161
|
+
* This helps prevent blocking the event loop in long-running operations.
|
|
162
|
+
* Only works in async schedulers; throws in sync schedulers.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* for (let i = 0; i < 10000; i++) {
|
|
166
|
+
* doWork(i);
|
|
167
|
+
* if (i % 100 === 0) {
|
|
168
|
+
* yield* new YieldEffect().run();
|
|
169
|
+
* }
|
|
170
|
+
* }
|
|
171
|
+
*/
|
|
172
|
+
declare class YieldEffect extends Effect<void> {
|
|
173
|
+
protected _executeSync(): void;
|
|
174
|
+
protected _executeAsync(): Promise<void>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Effect factory namespace for convenience.
|
|
178
|
+
* Provides static methods to create effects.
|
|
179
|
+
*/
|
|
180
|
+
declare const Effects: {
|
|
181
|
+
/**
|
|
182
|
+
* Create a pure effect that returns a value immediately.
|
|
183
|
+
*/
|
|
184
|
+
readonly pure: <T>(value: T) => PureEffect<T>;
|
|
185
|
+
/**
|
|
186
|
+
* Create a defer effect that wraps a Promise.
|
|
187
|
+
*/
|
|
188
|
+
readonly defer: <T>(promise: Promise<T>) => DeferEffect<T>;
|
|
189
|
+
/**
|
|
190
|
+
* Create a parallel effect that executes multiple effects concurrently.
|
|
191
|
+
*/
|
|
192
|
+
readonly parallel: (effects: readonly Effect<unknown>[]) => ParallelEffect;
|
|
193
|
+
/**
|
|
194
|
+
* Create a yield effect that returns control to the event loop.
|
|
195
|
+
*/
|
|
196
|
+
readonly yield: () => YieldEffect;
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region packages/common/src/scheduler/sync-scheduler.d.ts
|
|
200
|
+
/**
|
|
201
|
+
* Create a synchronous scheduler.
|
|
202
|
+
*
|
|
203
|
+
* This scheduler executes generators synchronously.
|
|
204
|
+
* It throws an error if an async-only effect (defer, yield) is encountered.
|
|
205
|
+
*
|
|
206
|
+
* @returns A SyncScheduler instance
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* const scheduler = createSyncScheduler();
|
|
210
|
+
* const result = scheduler.run(function* () {
|
|
211
|
+
* const a = yield* new PureEffect(1).run();
|
|
212
|
+
* const b = yield* new PureEffect(2).run();
|
|
213
|
+
* return a + b;
|
|
214
|
+
* });
|
|
215
|
+
* // result = ok(3)
|
|
216
|
+
*/
|
|
217
|
+
declare const createSyncScheduler: () => SyncScheduler;
|
|
218
|
+
//#endregion
|
|
219
|
+
export { type AsyncScheduler, CanonicalId, CanonicalIdSchema, CanonicalPathTracker, DeferEffect, Effect, type EffectGenerator, type EffectGeneratorFn, type EffectResult, Effects, HashAlgorithm, MODULE_EXTENSION_CANDIDATES, ParallelEffect, PortableFS, PortableHasher, PureEffect, type SchedulerError, SchemaFor, ScopeFrame, ScopeHandle, ShapeFor, SpawnOptions, SpawnResult, type SyncScheduler, YieldEffect, __resetPortableFSForTests, __resetPortableHasherForTests, buildAstPath, cachedFn, createAsyncScheduler, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, createPortableFS, createPortableHasher, createSchedulerError, createSyncScheduler, defineSchemaFor, generateId, getPortableFS, getPortableHasher, isExternalSpecifier, isRelativeSpecifier, normalizePath, once, resetPortableForTests, resolveRelativeImportWithExistenceCheck, resolveRelativeImportWithReferences, runtime, spawn };
|
|
220
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/scheduler/types.ts","../src/scheduler/async-scheduler.ts","../src/scheduler/effect.ts","../src/scheduler/sync-scheduler.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -2,5 +2,260 @@ import { a as getPortableHasher, c as getPortableFS, d as runtime, i as createPo
|
|
|
2
2
|
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "./utils-DLEgAn7q.mjs";
|
|
3
3
|
import { a as CanonicalIdSchema, i as createPathTracker, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, t as buildAstPath } from "./canonical-id-BFnyQGST.mjs";
|
|
4
4
|
import { t as defineSchemaFor } from "./zod-DeSimXdI.mjs";
|
|
5
|
+
import { err, ok } from "neverthrow";
|
|
5
6
|
|
|
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 ok(result.value);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (isSchedulerError$1(error)) {
|
|
101
|
+
return err(error);
|
|
102
|
+
}
|
|
103
|
+
return 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 ok(result.value);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (isSchedulerError(error)) {
|
|
245
|
+
return err(error);
|
|
246
|
+
}
|
|
247
|
+
return 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
|
|
260
|
+
export { CanonicalIdSchema, DeferEffect, Effect, Effects, MODULE_EXTENSION_CANDIDATES, ParallelEffect, PureEffect, YieldEffect, __resetPortableFSForTests, __resetPortableHasherForTests, buildAstPath, cachedFn, createAsyncScheduler, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker, createPortableFS, createPortableHasher, createSchedulerError, createSyncScheduler, defineSchemaFor, generateId, getPortableFS, getPortableHasher, isExternalSpecifier, isRelativeSpecifier, normalizePath, once, resetPortableForTests, resolveRelativeImportWithExistenceCheck, resolveRelativeImportWithReferences, runtime, spawn };
|
|
261
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soda-gql/common",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,40 +17,43 @@
|
|
|
17
17
|
"types": "./dist/index.d.mts",
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|
|
20
|
-
"
|
|
20
|
+
"@soda-gql": "./src/index.ts",
|
|
21
21
|
"types": "./dist/index.d.mts",
|
|
22
22
|
"import": "./dist/index.mjs",
|
|
23
23
|
"require": "./dist/index.cjs",
|
|
24
24
|
"default": "./dist/index.mjs"
|
|
25
25
|
},
|
|
26
26
|
"./portable": {
|
|
27
|
-
"
|
|
27
|
+
"@soda-gql": "./src/portable/index.ts",
|
|
28
28
|
"types": "./dist/portable/index.d.mts",
|
|
29
29
|
"import": "./dist/portable/index.mjs",
|
|
30
30
|
"require": "./dist/portable/index.cjs",
|
|
31
31
|
"default": "./dist/portable/index.mjs"
|
|
32
32
|
},
|
|
33
33
|
"./canonical-id": {
|
|
34
|
-
"
|
|
34
|
+
"@soda-gql": "./src/canonical-id/index.ts",
|
|
35
35
|
"types": "./dist/canonical-id/index.d.mts",
|
|
36
36
|
"import": "./dist/canonical-id/index.mjs",
|
|
37
37
|
"require": "./dist/canonical-id/index.cjs",
|
|
38
38
|
"default": "./dist/canonical-id/index.mjs"
|
|
39
39
|
},
|
|
40
40
|
"./utils": {
|
|
41
|
-
"
|
|
41
|
+
"@soda-gql": "./src/utils/index.ts",
|
|
42
42
|
"types": "./dist/utils/index.d.mts",
|
|
43
43
|
"import": "./dist/utils/index.mjs",
|
|
44
44
|
"require": "./dist/utils/index.cjs",
|
|
45
45
|
"default": "./dist/utils/index.mjs"
|
|
46
46
|
},
|
|
47
47
|
"./zod": {
|
|
48
|
-
"
|
|
48
|
+
"@soda-gql": "./src/zod/index.ts",
|
|
49
49
|
"types": "./dist/zod/index.d.mts",
|
|
50
50
|
"import": "./dist/zod/index.mjs",
|
|
51
51
|
"require": "./dist/zod/index.cjs",
|
|
52
52
|
"default": "./dist/zod/index.mjs"
|
|
53
53
|
},
|
|
54
|
+
"./test": {
|
|
55
|
+
"@soda-gql": "./test/export.ts"
|
|
56
|
+
},
|
|
54
57
|
"./package.json": "./package.json"
|
|
55
58
|
},
|
|
56
59
|
"dependencies": {
|