@dxos/effect 0.10.0 → 0.11.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/dist/lib/index.mjs +919 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/testing.mjs +23 -0
- package/dist/lib/testing.mjs.map +1 -0
- package/dist/types/src/EffectEx.d.ts +1 -1
- package/dist/types/src/EffectEx.d.ts.map +1 -1
- package/dist/types/src/RuntimeProvider.d.ts +6 -0
- package/dist/types/src/RuntimeProvider.d.ts.map +1 -1
- package/dist/types/src/atom-kvs.d.ts +7 -1
- package/dist/types/src/atom-kvs.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/errors.d.ts +0 -5
- package/dist/types/src/internal/errors.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -17
- package/src/EffectEx.ts +1 -9
- package/src/RuntimeProvider.ts +8 -0
- package/src/atom-kvs.ts +7 -1
- package/src/index.ts +1 -0
- package/src/internal/errors.ts +0 -16
- package/src/otel.test.ts +1 -1
- package/dist/lib/browser/chunk-CGS2ULMK.mjs +0 -11
- package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -849
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/testing.mjs +0 -31
- package/dist/lib/browser/testing.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -849
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing.mjs +0 -31
- package/dist/lib/node-esm/testing.mjs.map +0 -7
|
@@ -0,0 +1,919 @@
|
|
|
1
|
+
import { Atom } from "@effect-atom/atom";
|
|
2
|
+
import * as BrowserKeyValueStore from "@effect/platform-browser/BrowserKeyValueStore";
|
|
3
|
+
import * as Context$1 from "effect/Context";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as Exit from "effect/Exit";
|
|
6
|
+
import * as Option from "effect/Option";
|
|
7
|
+
import * as Runtime from "effect/Runtime";
|
|
8
|
+
import * as Cause from "effect/Cause";
|
|
9
|
+
import * as Chunk from "effect/Chunk";
|
|
10
|
+
import * as GlobalValue from "effect/GlobalValue";
|
|
11
|
+
import * as Function from "effect/Function";
|
|
12
|
+
import { pipe } from "effect/Function";
|
|
13
|
+
import * as Layer from "effect/Layer";
|
|
14
|
+
import * as Predicate from "effect/Predicate";
|
|
15
|
+
import * as Tracer$1 from "effect/Tracer";
|
|
16
|
+
import { Context } from "@dxos/context";
|
|
17
|
+
import * as Resource from "@effect/opentelemetry/Resource";
|
|
18
|
+
import * as Tracer from "@effect/opentelemetry/Tracer";
|
|
19
|
+
import { trace } from "@opentelemetry/api";
|
|
20
|
+
import * as Schema from "effect/Schema";
|
|
21
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
22
|
+
import { invariant } from "@dxos/invariant";
|
|
23
|
+
import { decamelize, getDeep, isNonNullable, setDeep } from "@dxos/util";
|
|
24
|
+
import { JSONPath } from "jsonpath-plus";
|
|
25
|
+
//#region \0rolldown/runtime.js
|
|
26
|
+
var __defProp = Object.defineProperty;
|
|
27
|
+
var __exportAll = (all, no_symbols) => {
|
|
28
|
+
let target = {};
|
|
29
|
+
for (var name in all) __defProp(target, name, {
|
|
30
|
+
get: all[name],
|
|
31
|
+
enumerable: true
|
|
32
|
+
});
|
|
33
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
34
|
+
return target;
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/atom-kvs.ts
|
|
38
|
+
var defaultRuntime = Atom.runtime(BrowserKeyValueStore.layerLocalStorage);
|
|
39
|
+
/**
|
|
40
|
+
* Creates a KVS-backed atom for structured settings using Atom.kvs.
|
|
41
|
+
* The entire object is stored as a single localStorage key with JSON serialization.
|
|
42
|
+
*
|
|
43
|
+
* @param options.key - The localStorage key to store the value under.
|
|
44
|
+
* @param options.schema - Effect Schema for the value type.
|
|
45
|
+
* @param options.defaultValue - Function returning the default value.
|
|
46
|
+
* @param options.runtime - Optional custom Atom runtime (defaults to localStorage).
|
|
47
|
+
* @returns A writable atom that persists to localStorage.
|
|
48
|
+
*
|
|
49
|
+
* @idiom org.dxos.effect.kvsStore
|
|
50
|
+
* applies: Persisting a plugin's settings/config as one schema-validated localStorage blob (a global user preference set infrequently)
|
|
51
|
+
* instead-of: hand-rolled localStorage reads/writes, or scattering per-field atoms, or using this for per-context UI state
|
|
52
|
+
* uses: {@link createKvsStore}
|
|
53
|
+
* related: org.dxos.react-ui-attention.viewState
|
|
54
|
+
*/
|
|
55
|
+
var createKvsStore = (options) => {
|
|
56
|
+
const runtime = options.runtime ?? defaultRuntime;
|
|
57
|
+
return Atom.kvs({
|
|
58
|
+
runtime,
|
|
59
|
+
key: options.key,
|
|
60
|
+
schema: options.schema,
|
|
61
|
+
defaultValue: options.defaultValue
|
|
62
|
+
}).pipe(Atom.keepAlive);
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/internal/errors.ts
|
|
66
|
+
var spanSymbol = Symbol.for("effect/SpanAnnotation");
|
|
67
|
+
var spanToTrace = GlobalValue.globalValue("effect/Tracer/spanToTrace", () => /* @__PURE__ */ new WeakMap());
|
|
68
|
+
var locationRegex = /\((.*)\)/g;
|
|
69
|
+
/**
|
|
70
|
+
* Adds effect spans.
|
|
71
|
+
* Removes effect internal functions.
|
|
72
|
+
* Unwraps error proxy.
|
|
73
|
+
*/
|
|
74
|
+
var prettyErrorStack = (error, appendStacks = []) => {
|
|
75
|
+
if (typeof error !== "object" || error === null) return error;
|
|
76
|
+
const span = error[spanSymbol];
|
|
77
|
+
const lines = typeof error.stack === "string" ? error.stack.split("\n") : [];
|
|
78
|
+
const out = [];
|
|
79
|
+
let atStack = false, inCore = false, passedScheduler = false;
|
|
80
|
+
for (let i = 0; i < lines.length; i++) {
|
|
81
|
+
if (!atStack && !lines[i].startsWith(" at ")) {
|
|
82
|
+
out.push(lines[i]);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
atStack = true;
|
|
86
|
+
if (lines[i].includes(" at new BaseEffectError") || lines[i].includes(" at new YieldableError")) {
|
|
87
|
+
i++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (lines[i].includes("Generator.next")) break;
|
|
91
|
+
if (lines[i].includes("effect_internal_function")) break;
|
|
92
|
+
const filename = lines[i].match(/\/([a-zA-Z0-9_\-.]+):\d+:\d+\)$/)?.[1];
|
|
93
|
+
if (!inCore && ["core-effect.ts"].includes(filename)) inCore = true;
|
|
94
|
+
if (inCore && !passedScheduler && ["Scheduler.ts"].includes(filename)) {
|
|
95
|
+
passedScheduler = true;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (passedScheduler && !["Scheduler.ts"].includes(filename)) inCore = false;
|
|
99
|
+
if (inCore) continue;
|
|
100
|
+
out.push(lines[i].replace(/at .*effect_instruction_i.*\((.*)\)/, "at $1").replace(/EffectPrimitive\.\w+/, "<anonymous>").replace(/at Arguments\./, "at "));
|
|
101
|
+
}
|
|
102
|
+
if (span) {
|
|
103
|
+
let current = span;
|
|
104
|
+
let i = 0;
|
|
105
|
+
while (current && current._tag === "Span" && i < 10) {
|
|
106
|
+
const stackFn = spanToTrace.get(current);
|
|
107
|
+
if (typeof stackFn === "function") {
|
|
108
|
+
const stack = stackFn();
|
|
109
|
+
if (typeof stack === "string") {
|
|
110
|
+
const locationMatchAll = stack.matchAll(locationRegex);
|
|
111
|
+
let match = false;
|
|
112
|
+
for (const [, location] of locationMatchAll) {
|
|
113
|
+
match = true;
|
|
114
|
+
out.push(` at ${current.name} (${location})`);
|
|
115
|
+
}
|
|
116
|
+
if (!match) out.push(` at ${current.name} (${stack.replace(/^at /, "")})`);
|
|
117
|
+
} else out.push(` at ${current.name}`);
|
|
118
|
+
} else out.push(` at ${current.name}`);
|
|
119
|
+
current = Option.getOrUndefined(current.parent);
|
|
120
|
+
i++;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
out.push(...appendStacks);
|
|
124
|
+
error = Cause.originalError(error);
|
|
125
|
+
if (error.cause) error.cause = prettyErrorStack(error.cause);
|
|
126
|
+
Object.defineProperty(error, "stack", {
|
|
127
|
+
value: out.join("\n"),
|
|
128
|
+
writable: true,
|
|
129
|
+
enumerable: false,
|
|
130
|
+
configurable: true
|
|
131
|
+
});
|
|
132
|
+
return error;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Converts a cause to an error.
|
|
136
|
+
* Inserts effect spans as stack frames.
|
|
137
|
+
* The error will have stack frames of where the effect was run (if stack trace limit allows).
|
|
138
|
+
* Removes effect runtime internal stack frames.
|
|
139
|
+
*
|
|
140
|
+
* To be used in place of `Effect.runPromise`.
|
|
141
|
+
*
|
|
142
|
+
* @throws AggregateError if there are multiple errors.
|
|
143
|
+
*/
|
|
144
|
+
var causeToError = (cause) => {
|
|
145
|
+
if (Cause.isEmpty(cause)) return /* @__PURE__ */ new Error("Fiber failed without a cause");
|
|
146
|
+
else if (Cause.isInterruptedOnly(cause)) return /* @__PURE__ */ new Error("Fiber was interrupted");
|
|
147
|
+
else {
|
|
148
|
+
const errors = [...Chunk.toArray(Cause.failures(cause)), ...Chunk.toArray(Cause.defects(cause))];
|
|
149
|
+
const getStackFrames = () => {
|
|
150
|
+
const err = /* @__PURE__ */ new Error();
|
|
151
|
+
Error.captureStackTrace(err, causeToError);
|
|
152
|
+
return err.stack.split("\n").slice(1);
|
|
153
|
+
};
|
|
154
|
+
const stackFrames = getStackFrames();
|
|
155
|
+
const newErrors = errors.map((error) => prettyErrorStack(error, stackFrames));
|
|
156
|
+
if (newErrors.length === 1) return newErrors[0];
|
|
157
|
+
else return new AggregateError(newErrors);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Throws an error based on the cause.
|
|
162
|
+
* Inserts effect spans as stack frames.
|
|
163
|
+
* The error will have stack frames of where the effect was run (if stack trace limit allows).
|
|
164
|
+
* Removes effect runtime internal stack frames.
|
|
165
|
+
*
|
|
166
|
+
* To be used in place of `Effect.runPromise`.
|
|
167
|
+
*
|
|
168
|
+
* @throws AggregateError if there are multiple errors.
|
|
169
|
+
*/
|
|
170
|
+
var throwCause = (cause) => {
|
|
171
|
+
throw causeToError(cause);
|
|
172
|
+
};
|
|
173
|
+
var unwrapExit = (exit) => {
|
|
174
|
+
if (Exit.isSuccess(exit)) return exit.value;
|
|
175
|
+
return throwCause(exit.cause);
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Runs the embedded effect asynchronously and throws any failures and defects as errors.
|
|
179
|
+
* Inserts effect spans as stack frames.
|
|
180
|
+
* The error will have stack frames of where the effect was run (if stack trace limit allows).
|
|
181
|
+
* Removes effect runtime internal stack frames.
|
|
182
|
+
*
|
|
183
|
+
* To be used in place of `Effect.runPromise`.
|
|
184
|
+
*
|
|
185
|
+
* @throws AggregateError if there are multiple errors.
|
|
186
|
+
*/
|
|
187
|
+
var runAndForwardErrors = async (effect, options) => {
|
|
188
|
+
return unwrapExit(await Effect.runPromiseExit(effect, options));
|
|
189
|
+
};
|
|
190
|
+
/** Alias for {@link runAndForwardErrors} — preferred name when accessed via `EffectEx.runPromise`. */
|
|
191
|
+
var runPromise$1 = runAndForwardErrors;
|
|
192
|
+
/**
|
|
193
|
+
* Runs the embedded effect asynchronously and throws any failures and defects as errors.
|
|
194
|
+
*/
|
|
195
|
+
var runInRuntime = (...args) => {
|
|
196
|
+
if (args.length === 1) {
|
|
197
|
+
const [runtime] = args;
|
|
198
|
+
return async (effect, options) => {
|
|
199
|
+
return unwrapExit(await Runtime.runPromiseExit(runtime, effect, options));
|
|
200
|
+
};
|
|
201
|
+
} else {
|
|
202
|
+
const [runtime, effect, options] = args;
|
|
203
|
+
return (async () => {
|
|
204
|
+
return unwrapExit(await Runtime.runPromiseExit(runtime, effect, options));
|
|
205
|
+
})();
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/dynamic-runtime.ts
|
|
210
|
+
var dynamic_runtime_exports = /* @__PURE__ */ __exportAll({ make: () => make });
|
|
211
|
+
/**
|
|
212
|
+
* Validate that all required tags are present in the runtime context.
|
|
213
|
+
*/
|
|
214
|
+
var validateTags = (context, tags) => Effect.gen(function* () {
|
|
215
|
+
const missingTags = [];
|
|
216
|
+
for (const tag of tags) {
|
|
217
|
+
const option = Context$1.getOption(context, tag);
|
|
218
|
+
if (Option.isNone(option)) missingTags.push(tag.key);
|
|
219
|
+
}
|
|
220
|
+
if (missingTags.length > 0) return yield* Effect.die(/* @__PURE__ */ new Error(`Missing required tags in runtime: ${missingTags.join(", ")}`));
|
|
221
|
+
});
|
|
222
|
+
/**
|
|
223
|
+
* Create a dynamic runtime from a managed runtime and validate required tags.
|
|
224
|
+
*/
|
|
225
|
+
function make(managedRuntime, tags) {
|
|
226
|
+
const managedRuntimeAny = managedRuntime;
|
|
227
|
+
let cachedRuntime;
|
|
228
|
+
let validatedRuntimePromise;
|
|
229
|
+
const getValidatedRuntimeAsync = async () => {
|
|
230
|
+
if (!validatedRuntimePromise) validatedRuntimePromise = managedRuntimeAny.runPromise(Effect.gen(function* () {
|
|
231
|
+
const rt = yield* managedRuntimeAny.runtimeEffect;
|
|
232
|
+
yield* validateTags(rt.context, tags);
|
|
233
|
+
return rt;
|
|
234
|
+
}));
|
|
235
|
+
return validatedRuntimePromise;
|
|
236
|
+
};
|
|
237
|
+
const getValidatedRuntime = () => {
|
|
238
|
+
return unwrapExit(managedRuntimeAny.runSyncExit(Effect.gen(function* () {
|
|
239
|
+
const rt = yield* managedRuntimeAny.runtimeEffect;
|
|
240
|
+
yield* validateTags(rt.context, tags);
|
|
241
|
+
return rt;
|
|
242
|
+
})));
|
|
243
|
+
};
|
|
244
|
+
return {
|
|
245
|
+
managedRuntime: managedRuntimeAny,
|
|
246
|
+
runPromise: async (effect) => {
|
|
247
|
+
const runtime = await getValidatedRuntimeAsync();
|
|
248
|
+
return Runtime.runPromise(runtime)(effect);
|
|
249
|
+
},
|
|
250
|
+
runSync: (effect) => {
|
|
251
|
+
const runtime = getValidatedRuntime();
|
|
252
|
+
return Runtime.runSync(runtime)(effect);
|
|
253
|
+
},
|
|
254
|
+
runSyncExit: (effect) => {
|
|
255
|
+
const validationExit = managedRuntimeAny.runSyncExit(Effect.gen(function* () {
|
|
256
|
+
const rt = yield* managedRuntimeAny.runtimeEffect;
|
|
257
|
+
yield* validateTags(rt.context, tags);
|
|
258
|
+
return rt;
|
|
259
|
+
}));
|
|
260
|
+
if (Exit.isSuccess(validationExit)) {
|
|
261
|
+
const runtime = validationExit.value;
|
|
262
|
+
return Runtime.runSyncExit(runtime)(effect);
|
|
263
|
+
}
|
|
264
|
+
return validationExit;
|
|
265
|
+
},
|
|
266
|
+
runPromiseExit: async (effect) => {
|
|
267
|
+
try {
|
|
268
|
+
const runtime = await getValidatedRuntimeAsync();
|
|
269
|
+
return Runtime.runPromiseExit(runtime)(effect);
|
|
270
|
+
} catch (error) {
|
|
271
|
+
return Exit.die(error);
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
runFork: (effect) => {
|
|
275
|
+
const runtime = getValidatedRuntime();
|
|
276
|
+
return Runtime.runFork(runtime)(effect);
|
|
277
|
+
},
|
|
278
|
+
runtimeEffect: Effect.gen(function* () {
|
|
279
|
+
if (cachedRuntime) return cachedRuntime;
|
|
280
|
+
const rt = yield* managedRuntimeAny.runtimeEffect;
|
|
281
|
+
yield* validateTags(rt.context, tags);
|
|
282
|
+
const runtime = rt;
|
|
283
|
+
cachedRuntime = runtime;
|
|
284
|
+
return runtime;
|
|
285
|
+
}).pipe(Effect.catchAll(() => Effect.die(/* @__PURE__ */ new Error("Unexpected error in runtimeEffect validation")))),
|
|
286
|
+
dispose: async () => {
|
|
287
|
+
await managedRuntimeAny.dispose();
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/internal/async-task-tagging.ts
|
|
293
|
+
var runInTask = Symbol("runInTask");
|
|
294
|
+
/**
|
|
295
|
+
* Traces effect frames using console.createTask so that the proper stack-trace is visible in Chrome Devtools debugger.
|
|
296
|
+
*/
|
|
297
|
+
var asyncTaskTaggingLayer = () => {
|
|
298
|
+
if (Predicate.hasProperty(console, "createTask") === false) return Layer.empty;
|
|
299
|
+
return pipe(Effect.gen(function* () {
|
|
300
|
+
const oldTracer = yield* Effect.tracer;
|
|
301
|
+
return Tracer$1.make({
|
|
302
|
+
span: (name, ...args) => {
|
|
303
|
+
const span = oldTracer.span(name, ...args);
|
|
304
|
+
const trace = console.createTask(name);
|
|
305
|
+
span[runInTask] = (f) => trace.run(f);
|
|
306
|
+
return span;
|
|
307
|
+
},
|
|
308
|
+
context: (f, fiber) => {
|
|
309
|
+
const maybeParentSpan = Context$1.getOption(Tracer$1.ParentSpan)(fiber.currentContext);
|
|
310
|
+
if (maybeParentSpan._tag === "None") return oldTracer.context(f, fiber);
|
|
311
|
+
const parentSpan = maybeParentSpan.value;
|
|
312
|
+
if (parentSpan._tag === "ExternalSpan") return oldTracer.context(f, fiber);
|
|
313
|
+
const span = parentSpan;
|
|
314
|
+
if (runInTask in span && typeof span[runInTask] === "function") return span[runInTask](() => oldTracer.context(f, fiber));
|
|
315
|
+
return oldTracer.context(f, fiber);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}), Effect.map(Layer.setTracer), Layer.unwrapEffect);
|
|
319
|
+
};
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/internal/context.ts
|
|
322
|
+
var __dxlog_file$2 = "/__w/dxos/dxos/packages/common/effect/src/internal/context.ts";
|
|
323
|
+
var contextFromScope = () => Effect.gen(function* () {
|
|
324
|
+
const ctx = new Context(void 0, {
|
|
325
|
+
"~LogMeta": "~LogMeta",
|
|
326
|
+
F: __dxlog_file$2,
|
|
327
|
+
L: 13
|
|
328
|
+
});
|
|
329
|
+
yield* Effect.addFinalizer(() => Effect.promise(() => ctx.dispose()));
|
|
330
|
+
return ctx;
|
|
331
|
+
});
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region src/internal/resource.ts
|
|
334
|
+
/**
|
|
335
|
+
* Acquires a resource and releases it when the scope is closed.
|
|
336
|
+
*/
|
|
337
|
+
var acquireReleaseResource = (getResource) => Effect.acquireRelease(Effect.gen(function* () {
|
|
338
|
+
const resource = getResource();
|
|
339
|
+
yield* Effect.promise(async () => {
|
|
340
|
+
await resource.open?.();
|
|
341
|
+
});
|
|
342
|
+
return resource;
|
|
343
|
+
}), (resource) => Effect.promise(async () => {
|
|
344
|
+
await resource.close?.();
|
|
345
|
+
}));
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/EffectEx.ts
|
|
348
|
+
var EffectEx_exports = /* @__PURE__ */ __exportAll({
|
|
349
|
+
acquireReleaseResource: () => acquireReleaseResource,
|
|
350
|
+
asyncTaskTaggingLayer: () => asyncTaskTaggingLayer,
|
|
351
|
+
causeToError: () => causeToError,
|
|
352
|
+
contextFromScope: () => contextFromScope,
|
|
353
|
+
runAndForwardErrors: () => runAndForwardErrors,
|
|
354
|
+
runInRuntime: () => runInRuntime,
|
|
355
|
+
runPromise: () => runPromise$1,
|
|
356
|
+
throwCause: () => throwCause,
|
|
357
|
+
unwrapExit: () => unwrapExit
|
|
358
|
+
});
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region src/otel.ts
|
|
361
|
+
var layerOtel = (evaluate) => Layer.unwrapEffect(Effect.map(Effect.isEffect(evaluate) ? evaluate : Effect.sync(evaluate), (config) => {
|
|
362
|
+
const ResourceLive = Resource.layerFromEnv(config.resource && Resource.configToAttributes(config.resource));
|
|
363
|
+
const provider = trace.getTracerProvider();
|
|
364
|
+
const TracerLive = Layer.provide(Tracer.layer, Layer.succeed(Tracer.OtelTracerProvider, provider));
|
|
365
|
+
const MetricsLive = Layer.empty;
|
|
366
|
+
const LoggerLive = Layer.empty;
|
|
367
|
+
return Layer.mergeAll(TracerLive, MetricsLive, LoggerLive).pipe(Layer.provideMerge(ResourceLive));
|
|
368
|
+
}));
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region src/Performance.ts
|
|
371
|
+
var Performance_exports = /* @__PURE__ */ __exportAll({ addTrackEntry: () => addTrackEntry });
|
|
372
|
+
/**
|
|
373
|
+
* Puts the effect span on the performance timeline in DevTools.
|
|
374
|
+
*/
|
|
375
|
+
var addTrackEntry = (options) => (effect) => Effect.gen(function* () {
|
|
376
|
+
const start = performance.now();
|
|
377
|
+
const exit = yield* Effect.exit(effect);
|
|
378
|
+
const resolvedOptions = typeof options === "function" ? options(exit) : options;
|
|
379
|
+
performance.measure(resolvedOptions.name, {
|
|
380
|
+
start,
|
|
381
|
+
detail: {
|
|
382
|
+
...resolvedOptions.detail,
|
|
383
|
+
devtools: resolvedOptions.devtools
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
return yield* exit;
|
|
387
|
+
});
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/RuntimeProvider.ts
|
|
390
|
+
var RuntimeProvider_exports = /* @__PURE__ */ __exportAll({
|
|
391
|
+
currentRuntime: () => currentRuntime,
|
|
392
|
+
provide: () => provide,
|
|
393
|
+
runPromise: () => runPromise,
|
|
394
|
+
toLayer: () => toLayer
|
|
395
|
+
});
|
|
396
|
+
/**
|
|
397
|
+
* Bridges a runtime provider into a {@link Layer} exposing its services, so a stack that resolves
|
|
398
|
+
* dependencies via `RuntimeProvider.currentRuntime` can be provided from an existing runtime.
|
|
399
|
+
*/
|
|
400
|
+
var toLayer = (provider) => Layer.effectContext(Effect.map(provider, (runtime) => runtime.context));
|
|
401
|
+
/**
|
|
402
|
+
* @returns Runtime provider from the current context.
|
|
403
|
+
*/
|
|
404
|
+
var currentRuntime = () => Effect.runtime().pipe(Effect.map(Effect.succeed));
|
|
405
|
+
/**
|
|
406
|
+
* Run effect, within runitme, clean errors and fix stack-traces.
|
|
407
|
+
*/
|
|
408
|
+
var runPromise = (provider) => async (effect) => {
|
|
409
|
+
const runtime = await runAndForwardErrors(provider);
|
|
410
|
+
return unwrapExit(await effect.pipe(Runtime.runPromiseExit(runtime)));
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* Provide services from runtime provider to effect.
|
|
414
|
+
*/
|
|
415
|
+
var provide = (runtimeProvider) => (effect) => Effect.flatMap(runtimeProvider, (runtime) => Effect.provide(effect, runtime));
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/internal/ast.ts
|
|
418
|
+
var __dxlog_file$1 = "/__w/dxos/dxos/packages/common/effect/src/internal/ast.ts";
|
|
419
|
+
/**
|
|
420
|
+
* Unwraps and collects refinement filters.
|
|
421
|
+
*/
|
|
422
|
+
var reduceRefinements = (type, refinements = []) => {
|
|
423
|
+
if (SchemaAST.isRefinement(type)) {
|
|
424
|
+
const filter = type.filter;
|
|
425
|
+
return reduceRefinements({
|
|
426
|
+
...type.from,
|
|
427
|
+
annotations: {
|
|
428
|
+
...type.from.annotations,
|
|
429
|
+
...type.annotations
|
|
430
|
+
}
|
|
431
|
+
}, [...refinements, filter]);
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
type,
|
|
435
|
+
refinements
|
|
436
|
+
};
|
|
437
|
+
};
|
|
438
|
+
/**
|
|
439
|
+
* Get the base type of a property.
|
|
440
|
+
*
|
|
441
|
+
* Unwraps refinements and optional unions.
|
|
442
|
+
*/
|
|
443
|
+
var getBaseType = (prop) => {
|
|
444
|
+
const encoded = SchemaAST.encodedBoundAST(prop.type);
|
|
445
|
+
return reduceRefinements(prop.isOptional && encoded._tag === "Union" ? encoded.types[0] : encoded);
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* Get the property types of an AST.
|
|
449
|
+
*/
|
|
450
|
+
var getProperties = (ast) => {
|
|
451
|
+
return SchemaAST.getPropertySignatures(ast).map((prop) => {
|
|
452
|
+
const { type, refinements } = getBaseType(prop);
|
|
453
|
+
return {
|
|
454
|
+
type: prop.annotations && Reflect.ownKeys(prop.annotations).length > 0 ? {
|
|
455
|
+
...type,
|
|
456
|
+
annotations: {
|
|
457
|
+
...type.annotations,
|
|
458
|
+
...prop.annotations
|
|
459
|
+
}
|
|
460
|
+
} : type,
|
|
461
|
+
refinements,
|
|
462
|
+
name: prop.name,
|
|
463
|
+
isOptional: prop.isOptional,
|
|
464
|
+
isReadonly: prop.isReadonly
|
|
465
|
+
};
|
|
466
|
+
});
|
|
467
|
+
};
|
|
468
|
+
var VisitResult = /* @__PURE__ */ function(VisitResult) {
|
|
469
|
+
VisitResult[VisitResult["CONTINUE"] = 0] = "CONTINUE";
|
|
470
|
+
/**
|
|
471
|
+
* Skip visiting children.
|
|
472
|
+
*/
|
|
473
|
+
VisitResult[VisitResult["SKIP"] = 1] = "SKIP";
|
|
474
|
+
/**
|
|
475
|
+
* Stop traversing immediately.
|
|
476
|
+
*/
|
|
477
|
+
VisitResult[VisitResult["EXIT"] = 2] = "EXIT";
|
|
478
|
+
return VisitResult;
|
|
479
|
+
}({});
|
|
480
|
+
/**
|
|
481
|
+
* Visit leaf nodes.
|
|
482
|
+
* Refs:
|
|
483
|
+
* - https://github.com/syntax-tree/unist-util-visit?tab=readme-ov-file#visitor
|
|
484
|
+
* - https://github.com/syntax-tree/unist-util-is?tab=readme-ov-file#test
|
|
485
|
+
*/
|
|
486
|
+
var visit = (node, testOrVisitor, visitor) => {
|
|
487
|
+
visitNode(node, testOrVisitor, visitor);
|
|
488
|
+
};
|
|
489
|
+
var visitNode = (node, test, visitor, path = [], depth = 0) => {
|
|
490
|
+
const $result = test?.(node, path, depth);
|
|
491
|
+
const result = $result === void 0 ? 0 : typeof $result === "boolean" ? $result ? 0 : 1 : $result;
|
|
492
|
+
if (result === 2) return result;
|
|
493
|
+
if (result !== 1) visitor(node, path, depth);
|
|
494
|
+
if (SchemaAST.isTypeLiteral(node)) for (const prop of SchemaAST.getPropertySignatures(node)) {
|
|
495
|
+
const currentPath = [...path, prop.name.toString()];
|
|
496
|
+
const result = visitNode(prop.type, test, visitor, currentPath, depth + 1);
|
|
497
|
+
if (result === 2) return result;
|
|
498
|
+
}
|
|
499
|
+
else if (SchemaAST.isTupleType(node)) for (const [i, element] of node.elements.entries()) {
|
|
500
|
+
const currentPath = [...path, i];
|
|
501
|
+
const result = visitNode(element.type, test, visitor, currentPath, depth);
|
|
502
|
+
if (result === 2) return result;
|
|
503
|
+
}
|
|
504
|
+
else if (SchemaAST.isUnion(node)) for (const type of node.types) {
|
|
505
|
+
const result = visitNode(type, test, visitor, path, depth);
|
|
506
|
+
if (result === 2) return result;
|
|
507
|
+
}
|
|
508
|
+
else if (SchemaAST.isRefinement(node)) {
|
|
509
|
+
const result = visitNode(node.from, test, visitor, path, depth);
|
|
510
|
+
if (result === 2) return result;
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
/**
|
|
514
|
+
* Recursively descend into AST to find first node that passes the test.
|
|
515
|
+
*/
|
|
516
|
+
var findNode = (node, test) => {
|
|
517
|
+
if (test(node)) return node;
|
|
518
|
+
else if (SchemaAST.isTypeLiteral(node)) {
|
|
519
|
+
for (const prop of SchemaAST.getPropertySignatures(node)) {
|
|
520
|
+
const child = findNode(prop.type, test);
|
|
521
|
+
if (child) return child;
|
|
522
|
+
}
|
|
523
|
+
for (const prop of getIndexSignatures(node)) {
|
|
524
|
+
const child = findNode(prop.type, test);
|
|
525
|
+
if (child) return child;
|
|
526
|
+
}
|
|
527
|
+
} else if (SchemaAST.isTupleType(node)) for (const [_, element] of node.elements.entries()) {
|
|
528
|
+
const child = findNode(element.type, test);
|
|
529
|
+
if (child) return child;
|
|
530
|
+
}
|
|
531
|
+
else if (SchemaAST.isUnion(node)) {
|
|
532
|
+
if (isLiteralUnion(node)) return;
|
|
533
|
+
for (const type of node.types) {
|
|
534
|
+
const child = findNode(type, test);
|
|
535
|
+
if (child) return child;
|
|
536
|
+
}
|
|
537
|
+
} else if (SchemaAST.isRefinement(node)) return findNode(node.from, test);
|
|
538
|
+
};
|
|
539
|
+
/**
|
|
540
|
+
* Get the AST node for the given property (dot-path).
|
|
541
|
+
*/
|
|
542
|
+
var findProperty = (schema, path) => {
|
|
543
|
+
const getProp = (node, path) => {
|
|
544
|
+
const [name, ...rest] = path;
|
|
545
|
+
const typeNode = findNode(node, SchemaAST.isTypeLiteral);
|
|
546
|
+
invariant(typeNode, void 0, {
|
|
547
|
+
"~LogMeta": "~LogMeta",
|
|
548
|
+
F: __dxlog_file$1,
|
|
549
|
+
L: 247,
|
|
550
|
+
S: void 0,
|
|
551
|
+
A: ["typeNode", ""]
|
|
552
|
+
});
|
|
553
|
+
for (const prop of SchemaAST.getPropertySignatures(typeNode)) if (prop.name === name) if (rest.length) return getProp(prop.type, rest);
|
|
554
|
+
else return prop.type;
|
|
555
|
+
};
|
|
556
|
+
return getProp(schema.ast, path.split("."));
|
|
557
|
+
};
|
|
558
|
+
var defaultAnnotations = {
|
|
559
|
+
ObjectKeyword: SchemaAST.objectKeyword,
|
|
560
|
+
StringKeyword: SchemaAST.stringKeyword,
|
|
561
|
+
NumberKeyword: SchemaAST.numberKeyword,
|
|
562
|
+
BooleanKeyword: SchemaAST.booleanKeyword
|
|
563
|
+
};
|
|
564
|
+
/**
|
|
565
|
+
* Get annotation or return undefined.
|
|
566
|
+
* @param annotationId
|
|
567
|
+
* @param noDefault If true, then return undefined for effect library defined values.
|
|
568
|
+
*/
|
|
569
|
+
var getAnnotation = (annotationId, noDefault = true) => (node) => {
|
|
570
|
+
const id = Function.pipe(SchemaAST.getIdentifierAnnotation(node), Option.getOrUndefined);
|
|
571
|
+
const value = Function.pipe(SchemaAST.getAnnotation(annotationId)(node), Option.getOrUndefined);
|
|
572
|
+
if (noDefault && (value === defaultAnnotations[node._tag]?.annotations[annotationId] || value === id)) return;
|
|
573
|
+
return value;
|
|
574
|
+
};
|
|
575
|
+
/**
|
|
576
|
+
* Recursively descend into AST to find first matching annotations.
|
|
577
|
+
* Optionally skips default annotations for basic types (e.g., 'a string').
|
|
578
|
+
*/
|
|
579
|
+
var findAnnotation = (node, annotationId, noDefault = true) => {
|
|
580
|
+
const getAnnotationById = getAnnotation(annotationId, noDefault);
|
|
581
|
+
const getBaseAnnotation = (node) => {
|
|
582
|
+
const value = getAnnotationById(node);
|
|
583
|
+
if (value !== void 0) return value;
|
|
584
|
+
if (SchemaAST.isUnion(node)) {
|
|
585
|
+
if (isOption(node)) return getAnnotationById(node.types[0]);
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
return getBaseAnnotation(node);
|
|
589
|
+
};
|
|
590
|
+
/**
|
|
591
|
+
* Effect Schema.optional creates a union type with undefined as the second type.
|
|
592
|
+
*/
|
|
593
|
+
var isOption = (node) => {
|
|
594
|
+
return SchemaAST.isUnion(node) && node.types.length === 2 && SchemaAST.isUndefinedKeyword(node.types[1]);
|
|
595
|
+
};
|
|
596
|
+
/**
|
|
597
|
+
* Determines if the node is a union of literal types.
|
|
598
|
+
*/
|
|
599
|
+
var isLiteralUnion = (node) => {
|
|
600
|
+
return SchemaAST.isUnion(node) && node.types.every(SchemaAST.isLiteral);
|
|
601
|
+
};
|
|
602
|
+
/**
|
|
603
|
+
* Extracts the literal values from a schema that is a union of literals
|
|
604
|
+
* (e.g. `Schema.Literal('a', 'b')` or `Schema.Union(Schema.Literal('a'), Schema.Literal('b'))`).
|
|
605
|
+
* Returns an empty array if the schema is not a literal union.
|
|
606
|
+
*/
|
|
607
|
+
var getLiteralValues = (schema) => {
|
|
608
|
+
if (!isLiteralUnion(schema.ast)) return [];
|
|
609
|
+
return schema.ast.types.map((node) => node.literal);
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* Determines if the node is an array type.
|
|
613
|
+
*/
|
|
614
|
+
var isArrayType = (node) => {
|
|
615
|
+
return SchemaAST.isTupleType(node) && node.elements.length === 0 && node.rest.length === 1;
|
|
616
|
+
};
|
|
617
|
+
/**
|
|
618
|
+
* Get the type of the array elements.
|
|
619
|
+
*/
|
|
620
|
+
var getArrayElementType = (node) => {
|
|
621
|
+
return isArrayType(node) ? node.rest.at(0)?.type : void 0;
|
|
622
|
+
};
|
|
623
|
+
/**
|
|
624
|
+
* Determines if the node is a tuple type.
|
|
625
|
+
*/
|
|
626
|
+
var isTupleType = (node) => {
|
|
627
|
+
return SchemaAST.isTupleType(node) && node.elements.length > 0;
|
|
628
|
+
};
|
|
629
|
+
/**
|
|
630
|
+
* Determines if the node is a discriminated union.
|
|
631
|
+
*/
|
|
632
|
+
var isDiscriminatedUnion = (node) => {
|
|
633
|
+
return SchemaAST.isUnion(node) && !!getDiscriminatingProps(node)?.length;
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Get the discriminating properties for the given union type.
|
|
637
|
+
*/
|
|
638
|
+
var getDiscriminatingProps = (node) => {
|
|
639
|
+
invariant(SchemaAST.isUnion(node), void 0, {
|
|
640
|
+
"~LogMeta": "~LogMeta",
|
|
641
|
+
F: __dxlog_file$1,
|
|
642
|
+
L: 379,
|
|
643
|
+
S: void 0,
|
|
644
|
+
A: ["SchemaAST.isUnion(node)", ""]
|
|
645
|
+
});
|
|
646
|
+
if (isOption(node)) return;
|
|
647
|
+
return node.types.reduce((shared, type) => {
|
|
648
|
+
const props = SchemaAST.getPropertySignatures(type).filter((p) => SchemaAST.isLiteral(p.type)).map((p) => p.name.toString());
|
|
649
|
+
return shared.length === 0 ? props : shared.filter((prop) => props.includes(prop));
|
|
650
|
+
}, []);
|
|
651
|
+
};
|
|
652
|
+
/**
|
|
653
|
+
* Get the discriminated type for the given value.
|
|
654
|
+
*/
|
|
655
|
+
var getDiscriminatedType = (node, value = {}) => {
|
|
656
|
+
invariant(SchemaAST.isUnion(node), void 0, {
|
|
657
|
+
"~LogMeta": "~LogMeta",
|
|
658
|
+
F: __dxlog_file$1,
|
|
659
|
+
L: 403,
|
|
660
|
+
S: void 0,
|
|
661
|
+
A: ["SchemaAST.isUnion(node)", ""]
|
|
662
|
+
});
|
|
663
|
+
invariant(value, void 0, {
|
|
664
|
+
"~LogMeta": "~LogMeta",
|
|
665
|
+
F: __dxlog_file$1,
|
|
666
|
+
L: 404,
|
|
667
|
+
S: void 0,
|
|
668
|
+
A: ["value", ""]
|
|
669
|
+
});
|
|
670
|
+
const props = getDiscriminatingProps(node);
|
|
671
|
+
if (!props?.length) return;
|
|
672
|
+
for (const type of node.types) if (SchemaAST.getPropertySignatures(type).filter((prop) => props?.includes(prop.name.toString())).every((prop) => {
|
|
673
|
+
invariant(SchemaAST.isLiteral(prop.type), void 0, {
|
|
674
|
+
"~LogMeta": "~LogMeta",
|
|
675
|
+
F: __dxlog_file$1,
|
|
676
|
+
L: 415,
|
|
677
|
+
S: void 0,
|
|
678
|
+
A: ["SchemaAST.isLiteral(prop.type)", ""]
|
|
679
|
+
});
|
|
680
|
+
return prop.type.literal === value[prop.name.toString()];
|
|
681
|
+
})) return type;
|
|
682
|
+
const fields = Object.fromEntries(props.map((prop) => {
|
|
683
|
+
const literals = node.types.map((type) => {
|
|
684
|
+
const literal = SchemaAST.getPropertySignatures(type).find((p) => p.name.toString() === prop);
|
|
685
|
+
invariant(SchemaAST.isLiteral(literal.type), void 0, {
|
|
686
|
+
"~LogMeta": "~LogMeta",
|
|
687
|
+
F: __dxlog_file$1,
|
|
688
|
+
L: 433,
|
|
689
|
+
S: void 0,
|
|
690
|
+
A: ["SchemaAST.isLiteral(literal.type)", ""]
|
|
691
|
+
});
|
|
692
|
+
return literal.type.literal;
|
|
693
|
+
}).filter(isNonNullable);
|
|
694
|
+
return literals.length ? [prop, Schema.Literal(...literals)] : void 0;
|
|
695
|
+
}).filter(isNonNullable));
|
|
696
|
+
return Schema.Struct(fields).ast;
|
|
697
|
+
};
|
|
698
|
+
/**
|
|
699
|
+
* If a property signature is optional (T | undefined), returns the inner non-undefined AST node.
|
|
700
|
+
* Otherwise returns the property signature unchanged, preserving its annotations.
|
|
701
|
+
*/
|
|
702
|
+
var unwrapOptional = (property) => {
|
|
703
|
+
if (!property.isOptional || !SchemaAST.isUnion(property.type) || !isOption(property.type)) return property;
|
|
704
|
+
return property.type.types[0];
|
|
705
|
+
};
|
|
706
|
+
/**
|
|
707
|
+
* Determines if the node is a nested object type.
|
|
708
|
+
*/
|
|
709
|
+
var isNestedType = (node) => {
|
|
710
|
+
return SchemaAST.isDeclaration(node) || SchemaAST.isObjectKeyword(node) || SchemaAST.isTypeLiteral(node) || isTupleType(node) || isDiscriminatedUnion(node);
|
|
711
|
+
};
|
|
712
|
+
/**
|
|
713
|
+
* Maps AST nodes.
|
|
714
|
+
* The user is responsible for recursively calling {@link mapAst} on the SchemaAST.
|
|
715
|
+
* NOTE: Will evaluate suspended ASTs.
|
|
716
|
+
*/
|
|
717
|
+
var mapAst = (ast, f) => {
|
|
718
|
+
switch (ast._tag) {
|
|
719
|
+
case "TypeLiteral": return new SchemaAST.TypeLiteral(ast.propertySignatures.map((prop) => new SchemaAST.PropertySignature(prop.name, f(prop.type, prop.name), prop.isOptional, prop.isReadonly, prop.annotations)), ast.indexSignatures, ast.annotations);
|
|
720
|
+
case "Union": return SchemaAST.Union.make(ast.types.map(f), ast.annotations);
|
|
721
|
+
case "TupleType": return new SchemaAST.TupleType(ast.elements.map((t, index) => new SchemaAST.OptionalType(f(t.type, index), t.isOptional, t.annotations)), ast.rest.map((t) => new SchemaAST.Type(f(t.type, void 0), t.annotations)), ast.isReadonly, ast.annotations);
|
|
722
|
+
case "Suspend": {
|
|
723
|
+
const newAst = f(ast.f(), void 0);
|
|
724
|
+
return new SchemaAST.Suspend(() => newAst, ast.annotations);
|
|
725
|
+
}
|
|
726
|
+
default: return ast;
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
var getIndexSignatures = (ast) => {
|
|
730
|
+
const annotation = SchemaAST.getSurrogateAnnotation(ast);
|
|
731
|
+
if (Option.isSome(annotation)) return getIndexSignatures(annotation.value);
|
|
732
|
+
switch (ast._tag) {
|
|
733
|
+
case "TypeLiteral": return ast.indexSignatures.slice();
|
|
734
|
+
case "Suspend": return getIndexSignatures(ast.f());
|
|
735
|
+
case "Refinement": return getIndexSignatures(ast.from);
|
|
736
|
+
}
|
|
737
|
+
return [];
|
|
738
|
+
};
|
|
739
|
+
//#endregion
|
|
740
|
+
//#region src/internal/json-path.ts
|
|
741
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/common/effect/src/internal/json-path.ts";
|
|
742
|
+
var PATH_REGEX = /^($|[a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*|\[\d+\](?:\.)?)*$)/;
|
|
743
|
+
var PROP_REGEX = /^\w+$/;
|
|
744
|
+
/**
|
|
745
|
+
* https://www.ietf.org/archive/id/draft-goessner-dispatch-jsonpath-00.html
|
|
746
|
+
*/
|
|
747
|
+
var JsonPath = Schema.String.pipe(Schema.pattern(PATH_REGEX)).annotations({
|
|
748
|
+
title: "JSON path",
|
|
749
|
+
description: "JSON path to a property"
|
|
750
|
+
});
|
|
751
|
+
var JsonProp = Schema.NonEmptyString.pipe(Schema.pattern(PROP_REGEX, { message: () => "Property name must contain only letters, numbers, and underscores" }));
|
|
752
|
+
var isJsonPath = (value) => {
|
|
753
|
+
return Option.isSome(Schema.validateOption(JsonPath)(value));
|
|
754
|
+
};
|
|
755
|
+
/**
|
|
756
|
+
* Creates a JsonPath from an array of path segments.
|
|
757
|
+
*
|
|
758
|
+
* Currently supports:
|
|
759
|
+
* - Simple property access (e.g., 'foo.bar')
|
|
760
|
+
* - Array indexing with non-negative integers (e.g., 'foo[0]')
|
|
761
|
+
* - Identifiers starting with letters, underscore, or $ (e.g., '$foo', '_bar')
|
|
762
|
+
* - Dot notation for nested properties (e.g., 'foo.bar.baz')
|
|
763
|
+
*
|
|
764
|
+
* Does not support (yet?).
|
|
765
|
+
* - Recursive descent (..)
|
|
766
|
+
* - Wildcards (*)
|
|
767
|
+
* - Array slicing
|
|
768
|
+
* - Filters
|
|
769
|
+
* - Negative indices
|
|
770
|
+
*
|
|
771
|
+
* @param path Array of string or number segments
|
|
772
|
+
* @returns Valid JsonPath or undefined if invalid
|
|
773
|
+
*/
|
|
774
|
+
var createJsonPath = (path) => {
|
|
775
|
+
const candidatePath = path.map((p, i) => {
|
|
776
|
+
if (typeof p === "number") return `[${p}]`;
|
|
777
|
+
else return i === 0 ? p : `.${p}`;
|
|
778
|
+
}).join("");
|
|
779
|
+
invariant(isJsonPath(candidatePath), `Invalid JsonPath: ${candidatePath}`, {
|
|
780
|
+
"~LogMeta": "~LogMeta",
|
|
781
|
+
F: __dxlog_file,
|
|
782
|
+
L: 69,
|
|
783
|
+
S: void 0,
|
|
784
|
+
A: ["isJsonPath(candidatePath)", "`Invalid JsonPath: ${candidatePath}`"]
|
|
785
|
+
});
|
|
786
|
+
return candidatePath;
|
|
787
|
+
};
|
|
788
|
+
/**
|
|
789
|
+
* Converts Effect validation path format (e.g. "addresses.[0].zip")
|
|
790
|
+
* to JsonPath format (e.g., "addresses[0].zip")
|
|
791
|
+
*/
|
|
792
|
+
var fromEffectValidationPath = (effectPath) => {
|
|
793
|
+
const jsonPath = effectPath.replace(/\.\[(\d+)\]/g, "[$1]");
|
|
794
|
+
invariant(isJsonPath(jsonPath), `Invalid JsonPath: ${jsonPath}`, {
|
|
795
|
+
"~LogMeta": "~LogMeta",
|
|
796
|
+
F: __dxlog_file,
|
|
797
|
+
L: 80,
|
|
798
|
+
S: void 0,
|
|
799
|
+
A: ["isJsonPath(jsonPath)", "`Invalid JsonPath: ${jsonPath}`"]
|
|
800
|
+
});
|
|
801
|
+
return jsonPath;
|
|
802
|
+
};
|
|
803
|
+
/**
|
|
804
|
+
* Splits a JsonPath into its constituent parts.
|
|
805
|
+
* Handles property access and array indexing.
|
|
806
|
+
*/
|
|
807
|
+
var splitJsonPath = (path) => {
|
|
808
|
+
if (!isJsonPath(path)) return [];
|
|
809
|
+
return path.match(/[a-zA-Z_$][\w$]*|\[\d+\]/g)?.map((part) => part.replace(/[[\]]/g, "")).map((part) => {
|
|
810
|
+
const parsed = Number.parseInt(part, 10);
|
|
811
|
+
return Number.isNaN(parsed) ? part : parsed;
|
|
812
|
+
}) ?? [];
|
|
813
|
+
};
|
|
814
|
+
/**
|
|
815
|
+
* Applies a JsonPath to an object.
|
|
816
|
+
*/
|
|
817
|
+
var getField = (object, path) => {
|
|
818
|
+
return JSONPath({
|
|
819
|
+
path,
|
|
820
|
+
json: object
|
|
821
|
+
})[0];
|
|
822
|
+
};
|
|
823
|
+
/**
|
|
824
|
+
* Get value from object using JsonPath.
|
|
825
|
+
*/
|
|
826
|
+
var getValue = (obj, path) => {
|
|
827
|
+
return getDeep(obj, splitJsonPath(path));
|
|
828
|
+
};
|
|
829
|
+
/**
|
|
830
|
+
* Set value on object using JsonPath.
|
|
831
|
+
*/
|
|
832
|
+
var setValue = (obj, path, value) => {
|
|
833
|
+
return setDeep(obj, splitJsonPath(path), value);
|
|
834
|
+
};
|
|
835
|
+
//#endregion
|
|
836
|
+
//#region src/internal/url.ts
|
|
837
|
+
var ParamKeyAnnotationId = Symbol.for("@dxos/schema/annotation/ParamKey");
|
|
838
|
+
var getParamKeyAnnotation = SchemaAST.getAnnotation(ParamKeyAnnotationId);
|
|
839
|
+
var ParamKeyAnnotation = (value) => (self) => self.annotations({ [ParamKeyAnnotationId]: value });
|
|
840
|
+
/**
|
|
841
|
+
* HTTP params parser.
|
|
842
|
+
* Supports custom key serialization.
|
|
843
|
+
*/
|
|
844
|
+
var UrlParser = class {
|
|
845
|
+
_schema;
|
|
846
|
+
constructor(_schema) {
|
|
847
|
+
this._schema = _schema;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Parse URL params.
|
|
851
|
+
*/
|
|
852
|
+
parse(_url) {
|
|
853
|
+
const url = new URL(_url);
|
|
854
|
+
return Object.entries(this._schema.fields).reduce((params, [key, type]) => {
|
|
855
|
+
let value = url.searchParams.get(decamelize(key));
|
|
856
|
+
if (value == null) value = url.searchParams.get(key);
|
|
857
|
+
if (value != null) if (SchemaAST.isNumberKeyword(type.ast)) params[key] = parseInt(value);
|
|
858
|
+
else if (SchemaAST.isBooleanKeyword(type.ast)) params[key] = value === "true" || value === "1";
|
|
859
|
+
else params[key] = value;
|
|
860
|
+
return params;
|
|
861
|
+
}, {});
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Return URL with encoded params.
|
|
865
|
+
*/
|
|
866
|
+
create(_url, params) {
|
|
867
|
+
const url = new URL(_url);
|
|
868
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
869
|
+
if (value !== void 0) {
|
|
870
|
+
const field = this._schema.fields[key];
|
|
871
|
+
if (field) {
|
|
872
|
+
const { key: serializedKey } = Function.pipe(getParamKeyAnnotation(field.ast), Option.getOrElse(() => ({ key: decamelize(key) })));
|
|
873
|
+
url.searchParams.set(serializedKey, String(value));
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
return url;
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/SchemaEx.ts
|
|
882
|
+
var SchemaEx_exports = /* @__PURE__ */ __exportAll({
|
|
883
|
+
JsonPath: () => JsonPath,
|
|
884
|
+
JsonProp: () => JsonProp,
|
|
885
|
+
ParamKeyAnnotation: () => ParamKeyAnnotation,
|
|
886
|
+
UrlParser: () => UrlParser,
|
|
887
|
+
VisitResult: () => VisitResult,
|
|
888
|
+
createJsonPath: () => createJsonPath,
|
|
889
|
+
findAnnotation: () => findAnnotation,
|
|
890
|
+
findNode: () => findNode,
|
|
891
|
+
findProperty: () => findProperty,
|
|
892
|
+
fromEffectValidationPath: () => fromEffectValidationPath,
|
|
893
|
+
getAnnotation: () => getAnnotation,
|
|
894
|
+
getArrayElementType: () => getArrayElementType,
|
|
895
|
+
getBaseType: () => getBaseType,
|
|
896
|
+
getDiscriminatedType: () => getDiscriminatedType,
|
|
897
|
+
getDiscriminatingProps: () => getDiscriminatingProps,
|
|
898
|
+
getField: () => getField,
|
|
899
|
+
getLiteralValues: () => getLiteralValues,
|
|
900
|
+
getParamKeyAnnotation: () => getParamKeyAnnotation,
|
|
901
|
+
getProperties: () => getProperties,
|
|
902
|
+
getValue: () => getValue,
|
|
903
|
+
isArrayType: () => isArrayType,
|
|
904
|
+
isDiscriminatedUnion: () => isDiscriminatedUnion,
|
|
905
|
+
isJsonPath: () => isJsonPath,
|
|
906
|
+
isLiteralUnion: () => isLiteralUnion,
|
|
907
|
+
isNestedType: () => isNestedType,
|
|
908
|
+
isOption: () => isOption,
|
|
909
|
+
isTupleType: () => isTupleType,
|
|
910
|
+
mapAst: () => mapAst,
|
|
911
|
+
setValue: () => setValue,
|
|
912
|
+
splitJsonPath: () => splitJsonPath,
|
|
913
|
+
unwrapOptional: () => unwrapOptional,
|
|
914
|
+
visit: () => visit
|
|
915
|
+
});
|
|
916
|
+
//#endregion
|
|
917
|
+
export { dynamic_runtime_exports as DynamicRuntime, EffectEx_exports as EffectEx, Performance_exports as Performance, RuntimeProvider_exports as RuntimeProvider, SchemaEx_exports as SchemaEx, createKvsStore, layerOtel };
|
|
918
|
+
|
|
919
|
+
//# sourceMappingURL=index.mjs.map
|