@dxos/effect 0.8.4-main.7ace549 → 0.8.4-main.937b3ca

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
  2. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +330 -221
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing.mjs +38 -0
  7. package/dist/lib/browser/testing.mjs.map +7 -0
  8. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  9. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +330 -221
  11. package/dist/lib/node-esm/index.mjs.map +4 -4
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing.mjs +38 -0
  14. package/dist/lib/node-esm/testing.mjs.map +7 -0
  15. package/dist/types/src/RuntimeProvider.d.ts +21 -0
  16. package/dist/types/src/RuntimeProvider.d.ts.map +1 -0
  17. package/dist/types/src/ast.d.ts +33 -20
  18. package/dist/types/src/ast.d.ts.map +1 -1
  19. package/dist/types/src/atom-kvs.d.ts +19 -0
  20. package/dist/types/src/atom-kvs.d.ts.map +1 -0
  21. package/dist/types/src/dynamic-runtime.d.ts +56 -0
  22. package/dist/types/src/dynamic-runtime.d.ts.map +1 -0
  23. package/dist/types/src/dynamic-runtime.test.d.ts +2 -0
  24. package/dist/types/src/dynamic-runtime.test.d.ts.map +1 -0
  25. package/dist/types/src/errors.d.ts +4 -0
  26. package/dist/types/src/errors.d.ts.map +1 -1
  27. package/dist/types/src/index.d.ts +5 -3
  28. package/dist/types/src/index.d.ts.map +1 -1
  29. package/dist/types/src/json-path.d.ts +2 -2
  30. package/dist/types/src/json-path.d.ts.map +1 -1
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +26 -10
  33. package/src/RuntimeProvider.ts +35 -0
  34. package/src/ast.test.ts +9 -7
  35. package/src/ast.ts +78 -86
  36. package/src/atom-kvs.ts +35 -0
  37. package/src/dynamic-runtime.test.ts +465 -0
  38. package/src/dynamic-runtime.ts +195 -0
  39. package/src/errors.ts +17 -2
  40. package/src/index.ts +5 -3
  41. package/src/interrupt.test.ts +3 -1
  42. package/src/json-path.test.ts +7 -7
  43. package/src/json-path.ts +9 -12
  44. package/src/layers.test.ts +4 -2
  45. package/src/resource.ts +2 -2
  46. package/src/sanity.test.ts +6 -4
@@ -1,4 +1,7 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ import {
3
+ __export
4
+ } from "./chunk-HSLMI22Q.mjs";
2
5
 
3
6
  // src/ast.ts
4
7
  import * as Function from "effect/Function";
@@ -8,65 +11,49 @@ import * as SchemaAST from "effect/SchemaAST";
8
11
  import { invariant } from "@dxos/invariant";
9
12
  import { isNonNullable } from "@dxos/util";
10
13
  var __dxlog_file = "/__w/dxos/dxos/packages/common/effect/src/ast.ts";
11
- var isTupleType2 = (node) => {
12
- return SchemaAST.isTupleType(node) && node.elements.length > 0;
13
- };
14
- var getSimpleType = (node) => {
15
- if (SchemaAST.isDeclaration(node) || SchemaAST.isObjectKeyword(node) || SchemaAST.isTypeLiteral(node) || // TODO(wittjosiah): Tuples are actually arrays.
16
- isTupleType2(node) || isDiscriminatedUnion(node)) {
17
- return "object";
18
- }
19
- if (SchemaAST.isStringKeyword(node)) {
20
- return "string";
21
- }
22
- if (SchemaAST.isNumberKeyword(node)) {
23
- return "number";
24
- }
25
- if (SchemaAST.isBooleanKeyword(node)) {
26
- return "boolean";
27
- }
28
- if (SchemaAST.isEnums(node)) {
29
- return "enum";
30
- }
31
- if (SchemaAST.isLiteral(node)) {
32
- return "literal";
33
- }
34
- };
35
- var isSimpleType = (node) => !!getSimpleType(node);
36
- (function(SimpleType2) {
37
- SimpleType2.getDefaultValue = (type) => {
38
- switch (type) {
39
- case "string": {
40
- return "";
14
+ var reduceRefinements = (type, refinements = []) => {
15
+ if (SchemaAST.isRefinement(type)) {
16
+ const annotations = type.annotations;
17
+ const filter = type.filter;
18
+ const nextType = {
19
+ ...type.from,
20
+ annotations: {
21
+ ...type.annotations,
22
+ ...annotations
41
23
  }
42
- case "number": {
43
- return 0;
44
- }
45
- case "boolean": {
46
- return false;
47
- }
48
- case "object": {
49
- return {};
50
- }
51
- default: {
52
- throw new Error(`Unsupported type for default value: ${type}`);
53
- }
54
- }
24
+ };
25
+ return reduceRefinements(nextType, [
26
+ ...refinements,
27
+ filter
28
+ ]);
29
+ }
30
+ return {
31
+ type,
32
+ refinements
55
33
  };
56
- })(SimpleType || (SimpleType = {}));
34
+ };
35
+ var getBaseType = (prop) => {
36
+ const encoded = SchemaAST.encodedBoundAST(prop.type);
37
+ const unwrapped = prop.isOptional && encoded._tag === "Union" ? encoded.types[0] : encoded;
38
+ return reduceRefinements(unwrapped);
39
+ };
40
+ var getProperties = (ast) => {
41
+ const properties = SchemaAST.getPropertySignatures(ast);
42
+ return properties.map((prop) => ({
43
+ ...getBaseType(prop),
44
+ name: prop.name,
45
+ isOptional: prop.isOptional,
46
+ isReadonly: prop.isReadonly
47
+ }));
48
+ };
57
49
  var VisitResult = /* @__PURE__ */ (function(VisitResult2) {
58
50
  VisitResult2[VisitResult2["CONTINUE"] = 0] = "CONTINUE";
59
51
  VisitResult2[VisitResult2["SKIP"] = 1] = "SKIP";
60
52
  VisitResult2[VisitResult2["EXIT"] = 2] = "EXIT";
61
53
  return VisitResult2;
62
54
  })({});
63
- var defaultTest = isSimpleType;
64
55
  var visit = (node, testOrVisitor, visitor) => {
65
- if (!visitor) {
66
- visitNode(node, defaultTest, testOrVisitor);
67
- } else {
68
- visitNode(node, testOrVisitor, visitor);
69
- }
56
+ visitNode(node, testOrVisitor, visitor);
70
57
  };
71
58
  var visitNode = (node, test, visitor, path = [], depth = 0) => {
72
59
  const $result = test?.(node, path, depth);
@@ -156,7 +143,7 @@ var findProperty = (schema, path) => {
156
143
  const typeNode = findNode(node, SchemaAST.isTypeLiteral);
157
144
  invariant(typeNode, void 0, {
158
145
  F: __dxlog_file,
159
- L: 265,
146
+ L: 235,
160
147
  S: void 0,
161
148
  A: [
162
149
  "typeNode",
@@ -210,13 +197,22 @@ var isOption = (node) => {
210
197
  var isLiteralUnion = (node) => {
211
198
  return SchemaAST.isUnion(node) && node.types.every(SchemaAST.isLiteral);
212
199
  };
200
+ var isArrayType = (node) => {
201
+ return SchemaAST.isTupleType(node) && node.elements.length === 0 && node.rest.length === 1;
202
+ };
203
+ var getArrayElementType = (node) => {
204
+ return isArrayType(node) ? node.rest.at(0)?.type : void 0;
205
+ };
206
+ var isTupleType2 = (node) => {
207
+ return SchemaAST.isTupleType(node) && node.elements.length > 0;
208
+ };
213
209
  var isDiscriminatedUnion = (node) => {
214
210
  return SchemaAST.isUnion(node) && !!getDiscriminatingProps(node)?.length;
215
211
  };
216
212
  var getDiscriminatingProps = (node) => {
217
213
  invariant(SchemaAST.isUnion(node), void 0, {
218
214
  F: __dxlog_file,
219
- L: 362,
215
+ L: 353,
220
216
  S: void 0,
221
217
  A: [
222
218
  "SchemaAST.isUnion(node)",
@@ -234,7 +230,7 @@ var getDiscriminatingProps = (node) => {
234
230
  var getDiscriminatedType = (node, value = {}) => {
235
231
  invariant(SchemaAST.isUnion(node), void 0, {
236
232
  F: __dxlog_file,
237
- L: 386,
233
+ L: 377,
238
234
  S: void 0,
239
235
  A: [
240
236
  "SchemaAST.isUnion(node)",
@@ -243,7 +239,7 @@ var getDiscriminatedType = (node, value = {}) => {
243
239
  });
244
240
  invariant(value, void 0, {
245
241
  F: __dxlog_file,
246
- L: 387,
242
+ L: 378,
247
243
  S: void 0,
248
244
  A: [
249
245
  "value",
@@ -258,7 +254,7 @@ var getDiscriminatedType = (node, value = {}) => {
258
254
  const match = SchemaAST.getPropertySignatures(type).filter((prop) => props?.includes(prop.name.toString())).every((prop) => {
259
255
  invariant(SchemaAST.isLiteral(prop.type), void 0, {
260
256
  F: __dxlog_file,
261
- L: 398,
257
+ L: 389,
262
258
  S: void 0,
263
259
  A: [
264
260
  "SchemaAST.isLiteral(prop.type)",
@@ -276,7 +272,7 @@ var getDiscriminatedType = (node, value = {}) => {
276
272
  const literal = SchemaAST.getPropertySignatures(type).find((p) => p.name.toString() === prop);
277
273
  invariant(SchemaAST.isLiteral(literal.type), void 0, {
278
274
  F: __dxlog_file,
279
- L: 416,
275
+ L: 407,
280
276
  S: void 0,
281
277
  A: [
282
278
  "SchemaAST.isLiteral(literal.type)",
@@ -293,6 +289,10 @@ var getDiscriminatedType = (node, value = {}) => {
293
289
  const schema = Schema.Struct(fields);
294
290
  return schema.ast;
295
291
  };
292
+ var isNestedType = (node) => {
293
+ return SchemaAST.isDeclaration(node) || SchemaAST.isObjectKeyword(node) || SchemaAST.isTypeLiteral(node) || // TODO(wittjosiah): Tuples are actually arrays.
294
+ isTupleType2(node) || isDiscriminatedUnion(node);
295
+ };
296
296
  var mapAst = (ast, f) => {
297
297
  switch (ast._tag) {
298
298
  case "TypeLiteral": {
@@ -313,9 +313,6 @@ var mapAst = (ast, f) => {
313
313
  }
314
314
  }
315
315
  };
316
- var isArrayType = (node) => {
317
- return SchemaAST.isTupleType(node) || SchemaAST.isUnion(node) && node.types.some(isArrayType) && node.types.some(SchemaAST.isUndefinedKeyword) && node.types.length === 2;
318
- };
319
316
  var getIndexSignatures = (ast) => {
320
317
  const annotation = SchemaAST.getSurrogateAnnotation(ast);
321
318
  if (Option.isSome(annotation)) {
@@ -331,160 +328,61 @@ var getIndexSignatures = (ast) => {
331
328
  }
332
329
  return [];
333
330
  };
334
- var SimpleType;
335
-
336
- // src/json-path.ts
337
- import * as Option2 from "effect/Option";
338
- import * as Schema2 from "effect/Schema";
339
- import { JSONPath } from "jsonpath-plus";
340
- import { invariant as invariant2 } from "@dxos/invariant";
341
- import { getDeep, setDeep } from "@dxos/util";
342
- var __dxlog_file2 = "/__w/dxos/dxos/packages/common/effect/src/json-path.ts";
343
- var PATH_REGEX = /^($|[a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*|\[\d+\](?:\.)?)*$)/;
344
- var PROP_REGEX = /^\w+$/;
345
- var JsonPath = Schema2.String.pipe(Schema2.pattern(PATH_REGEX)).annotations({
346
- title: "JSON path",
347
- description: "JSON path to a property"
348
- });
349
- var JsonProp = Schema2.NonEmptyString.pipe(Schema2.pattern(PROP_REGEX, {
350
- message: () => "Property name must contain only letters, numbers, and underscores"
351
- }));
352
- var isJsonPath = (value) => {
353
- return Option2.isSome(Schema2.validateOption(JsonPath)(value));
354
- };
355
- var createJsonPath = (path) => {
356
- const candidatePath = path.map((p, i) => {
357
- if (typeof p === "number") {
358
- return `[${p}]`;
359
- } else {
360
- return i === 0 ? p : `.${p}`;
361
- }
362
- }).join("");
363
- invariant2(isJsonPath(candidatePath), `Invalid JsonPath: ${candidatePath}`, {
364
- F: __dxlog_file2,
365
- L: 69,
366
- S: void 0,
367
- A: [
368
- "isJsonPath(candidatePath)",
369
- "`Invalid JsonPath: ${candidatePath}`"
370
- ]
371
- });
372
- return candidatePath;
373
- };
374
- var fromEffectValidationPath = (effectPath) => {
375
- const jsonPath = effectPath.replace(/\.\[(\d+)\]/g, "[$1]");
376
- invariant2(isJsonPath(jsonPath), `Invalid JsonPath: ${jsonPath}`, {
377
- F: __dxlog_file2,
378
- L: 80,
379
- S: void 0,
380
- A: [
381
- "isJsonPath(jsonPath)",
382
- "`Invalid JsonPath: ${jsonPath}`"
383
- ]
384
- });
385
- return jsonPath;
386
- };
387
- var splitJsonPath = (path) => {
388
- if (!isJsonPath(path)) {
389
- return [];
390
- }
391
- return path.match(/[a-zA-Z_$][\w$]*|\[\d+\]/g)?.map((part) => part.startsWith("[") ? part.replace(/[[\]]/g, "") : part) ?? [];
392
- };
393
- var getField = (object, path) => {
394
- return JSONPath({
395
- path,
396
- json: object
397
- })[0];
398
- };
399
- var getValue = (obj, path) => {
400
- return getDeep(obj, splitJsonPath(path).map((p) => p.replace(/[[\]]/g, "")));
401
- };
402
- var setValue = (obj, path, value) => {
403
- return setDeep(obj, splitJsonPath(path).map((p) => p.replace(/[[\]]/g, "")), value);
404
- };
405
331
 
406
- // src/url.ts
407
- import * as Function2 from "effect/Function";
408
- import * as Option3 from "effect/Option";
409
- import * as SchemaAST2 from "effect/SchemaAST";
410
- import { decamelize } from "@dxos/util";
411
- var ParamKeyAnnotationId = Symbol.for("@dxos/schema/annotation/ParamKey");
412
- var getParamKeyAnnotation = SchemaAST2.getAnnotation(ParamKeyAnnotationId);
413
- var ParamKeyAnnotation = (value) => (self) => self.annotations({
414
- [ParamKeyAnnotationId]: value
415
- });
416
- var UrlParser = class {
417
- _schema;
418
- constructor(_schema) {
419
- this._schema = _schema;
420
- }
421
- /**
422
- * Parse URL params.
423
- */
424
- parse(_url) {
425
- const url = new URL(_url);
426
- return Object.entries(this._schema.fields).reduce((params, [key, type]) => {
427
- let value = url.searchParams.get(decamelize(key));
428
- if (value == null) {
429
- value = url.searchParams.get(key);
430
- }
431
- if (value != null) {
432
- if (SchemaAST2.isNumberKeyword(type.ast)) {
433
- params[key] = parseInt(value);
434
- } else if (SchemaAST2.isBooleanKeyword(type.ast)) {
435
- params[key] = value === "true" || value === "1";
436
- } else {
437
- params[key] = value;
438
- }
439
- }
440
- return params;
441
- }, {});
442
- }
443
- /**
444
- * Return URL with encoded params.
445
- */
446
- create(_url, params) {
447
- const url = new URL(_url);
448
- Object.entries(params).forEach(([key, value]) => {
449
- if (value !== void 0) {
450
- const field = this._schema.fields[key];
451
- if (field) {
452
- const { key: serializedKey } = Function2.pipe(getParamKeyAnnotation(field.ast), Option3.getOrElse(() => ({
453
- key: decamelize(key)
454
- })));
455
- url.searchParams.set(serializedKey, String(value));
456
- }
457
- }
458
- });
459
- return url;
460
- }
332
+ // src/atom-kvs.ts
333
+ import * as BrowserKeyValueStore from "@effect/platform-browser/BrowserKeyValueStore";
334
+ import { Atom } from "@effect-atom/atom-react";
335
+ var defaultRuntime = Atom.runtime(BrowserKeyValueStore.layerLocalStorage);
336
+ var createKvsStore = (options) => {
337
+ const runtime2 = options.runtime ?? defaultRuntime;
338
+ return Atom.kvs({
339
+ runtime: runtime2,
340
+ key: options.key,
341
+ schema: options.schema,
342
+ defaultValue: options.defaultValue
343
+ }).pipe(Atom.keepAlive);
461
344
  };
462
345
 
463
346
  // src/context.ts
464
347
  import * as Effect from "effect/Effect";
465
348
  import { Context } from "@dxos/context";
466
- var __dxlog_file3 = "/__w/dxos/dxos/packages/common/effect/src/context.ts";
349
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/common/effect/src/context.ts";
467
350
  var contextFromScope = () => Effect.gen(function* () {
468
351
  const ctx = new Context(void 0, {
469
- F: __dxlog_file3,
352
+ F: __dxlog_file2,
470
353
  L: 13
471
354
  });
472
355
  yield* Effect.addFinalizer(() => Effect.promise(() => ctx.dispose()));
473
356
  return ctx;
474
357
  });
475
358
 
359
+ // src/dynamic-runtime.ts
360
+ var dynamic_runtime_exports = {};
361
+ __export(dynamic_runtime_exports, {
362
+ make: () => make
363
+ });
364
+ import * as Context2 from "effect/Context";
365
+ import * as Effect3 from "effect/Effect";
366
+ import * as Exit2 from "effect/Exit";
367
+ import * as Option3 from "effect/Option";
368
+ import * as Runtime2 from "effect/Runtime";
369
+
476
370
  // src/errors.ts
477
371
  import * as Cause from "effect/Cause";
478
372
  import * as Chunk from "effect/Chunk";
479
373
  import * as Effect2 from "effect/Effect";
480
374
  import * as Exit from "effect/Exit";
481
375
  import * as GlobalValue from "effect/GlobalValue";
482
- import * as Option4 from "effect/Option";
376
+ import * as Option2 from "effect/Option";
377
+ import * as Runtime from "effect/Runtime";
483
378
  var spanSymbol = Symbol.for("effect/SpanAnnotation");
484
379
  var originalSymbol = Symbol.for("effect/OriginalAnnotation");
485
380
  var spanToTrace = GlobalValue.globalValue("effect/Tracer/spanToTrace", () => /* @__PURE__ */ new WeakMap());
486
381
  var locationRegex = /\((.*)\)/g;
487
382
  var prettyErrorStack = (error, appendStacks = []) => {
383
+ if (typeof error !== "object" || error === null) {
384
+ return error;
385
+ }
488
386
  const span = error[spanSymbol];
489
387
  const lines = typeof error.stack === "string" ? error.stack.split("\n") : [];
490
388
  const out = [];
@@ -530,7 +428,7 @@ var prettyErrorStack = (error, appendStacks = []) => {
530
428
  } else {
531
429
  out.push(` at ${current.name}`);
532
430
  }
533
- current = Option4.getOrUndefined(current.parent);
431
+ current = Option2.getOrUndefined(current.parent);
534
432
  i++;
535
433
  }
536
434
  }
@@ -560,7 +458,7 @@ var causeToError = (cause) => {
560
458
  ...Chunk.toArray(Cause.defects(cause))
561
459
  ];
562
460
  const getStackFrames = () => {
563
- const o = {};
461
+ const o = new Error();
564
462
  Error.captureStackTrace(o, getStackFrames);
565
463
  return o.stack.split("\n").slice(1);
566
464
  };
@@ -586,6 +484,10 @@ var runAndForwardErrors = async (effect, options) => {
586
484
  const exit = await Effect2.runPromiseExit(effect, options);
587
485
  return unwrapExit(exit);
588
486
  };
487
+ var runInRuntime = async (runtime2, effect, options) => {
488
+ const exit = await Runtime.runPromiseExit(runtime2, effect, options);
489
+ return unwrapExit(exit);
490
+ };
589
491
  var promiseWithCauseCapture = (evaluate) => Effect2.promise(async (signal) => {
590
492
  try {
591
493
  const result = await evaluate(signal);
@@ -595,83 +497,290 @@ var promiseWithCauseCapture = (evaluate) => Effect2.promise(async (signal) => {
595
497
  }
596
498
  }).pipe(Effect2.flatten);
597
499
 
598
- // src/testing.ts
599
- import * as Context2 from "effect/Context";
600
- import * as Effect3 from "effect/Effect";
601
- (function(TestHelpers2) {
602
- TestHelpers2.runIf = (condition) => (effect, ctx) => Effect3.gen(function* () {
603
- if (!condition) {
604
- ctx.skip();
605
- } else {
606
- return yield* effect;
500
+ // src/dynamic-runtime.ts
501
+ var validateTags = (context, tags) => Effect3.gen(function* () {
502
+ const missingTags = [];
503
+ for (const tag of tags) {
504
+ const option = Context2.getOption(context, tag);
505
+ if (Option3.isNone(option)) {
506
+ missingTags.push(tag.key);
607
507
  }
608
- });
609
- TestHelpers2.skipIf = (condition) => (effect, ctx) => Effect3.gen(function* () {
610
- if (condition) {
611
- ctx.skip();
612
- } else {
613
- return yield* effect;
508
+ }
509
+ if (missingTags.length > 0) {
510
+ return yield* Effect3.die(new Error(`Missing required tags in runtime: ${missingTags.join(", ")}`));
511
+ }
512
+ });
513
+ function make(managedRuntime, tags) {
514
+ const managedRuntimeAny = managedRuntime;
515
+ let cachedRuntime;
516
+ let validatedRuntimePromise;
517
+ const getValidatedRuntimeAsync = async () => {
518
+ if (!validatedRuntimePromise) {
519
+ validatedRuntimePromise = managedRuntimeAny.runPromise(Effect3.gen(function* () {
520
+ const rt = yield* managedRuntimeAny.runtimeEffect;
521
+ yield* validateTags(rt.context, tags);
522
+ return rt;
523
+ }));
614
524
  }
615
- });
616
- TestHelpers2.taggedTest = (tag) => (effect, ctx) => Effect3.gen(function* () {
617
- if (!process.env.DX_TEST_TAGS?.includes(tag)) {
618
- ctx.skip();
525
+ return validatedRuntimePromise;
526
+ };
527
+ const getValidatedRuntime = () => {
528
+ const validationExit = managedRuntimeAny.runSyncExit(Effect3.gen(function* () {
529
+ const rt = yield* managedRuntimeAny.runtimeEffect;
530
+ yield* validateTags(rt.context, tags);
531
+ return rt;
532
+ }));
533
+ return unwrapExit(validationExit);
534
+ };
535
+ return {
536
+ managedRuntime: managedRuntimeAny,
537
+ runPromise: async (effect) => {
538
+ const runtime2 = await getValidatedRuntimeAsync();
539
+ return Runtime2.runPromise(runtime2)(effect);
540
+ },
541
+ runSync: (effect) => {
542
+ const runtime2 = getValidatedRuntime();
543
+ return Runtime2.runSync(runtime2)(effect);
544
+ },
545
+ runSyncExit: (effect) => {
546
+ const validationExit = managedRuntimeAny.runSyncExit(Effect3.gen(function* () {
547
+ const rt = yield* managedRuntimeAny.runtimeEffect;
548
+ yield* validateTags(rt.context, tags);
549
+ return rt;
550
+ }));
551
+ if (Exit2.isSuccess(validationExit)) {
552
+ const runtime2 = validationExit.value;
553
+ return Runtime2.runSyncExit(runtime2)(effect);
554
+ }
555
+ return validationExit;
556
+ },
557
+ runPromiseExit: async (effect) => {
558
+ try {
559
+ const runtime2 = await getValidatedRuntimeAsync();
560
+ return Runtime2.runPromiseExit(runtime2)(effect);
561
+ } catch (error) {
562
+ return Exit2.die(error);
563
+ }
564
+ },
565
+ runFork: (effect) => {
566
+ const runtime2 = getValidatedRuntime();
567
+ return Runtime2.runFork(runtime2)(effect);
568
+ },
569
+ runtimeEffect: Effect3.gen(function* () {
570
+ if (cachedRuntime) {
571
+ return cachedRuntime;
572
+ }
573
+ const rt = yield* managedRuntimeAny.runtimeEffect;
574
+ yield* validateTags(rt.context, tags);
575
+ const runtime2 = rt;
576
+ cachedRuntime = runtime2;
577
+ return runtime2;
578
+ }).pipe(Effect3.catchAll(() => (
579
+ // This should never happen since validateTags uses Effect.die
580
+ Effect3.die(new Error("Unexpected error in runtimeEffect validation"))
581
+ ))),
582
+ dispose: async () => {
583
+ await managedRuntimeAny.dispose();
584
+ }
585
+ };
586
+ }
587
+
588
+ // src/json-path.ts
589
+ import * as Option4 from "effect/Option";
590
+ import * as Schema2 from "effect/Schema";
591
+ import { JSONPath } from "jsonpath-plus";
592
+ import { invariant as invariant2 } from "@dxos/invariant";
593
+ import { getDeep, setDeep } from "@dxos/util";
594
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/common/effect/src/json-path.ts";
595
+ var PATH_REGEX = /^($|[a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*|\[\d+\](?:\.)?)*$)/;
596
+ var PROP_REGEX = /^\w+$/;
597
+ var JsonPath = Schema2.String.pipe(Schema2.pattern(PATH_REGEX)).annotations({
598
+ title: "JSON path",
599
+ description: "JSON path to a property"
600
+ });
601
+ var JsonProp = Schema2.NonEmptyString.pipe(Schema2.pattern(PROP_REGEX, {
602
+ message: () => "Property name must contain only letters, numbers, and underscores"
603
+ }));
604
+ var isJsonPath = (value) => {
605
+ return Option4.isSome(Schema2.validateOption(JsonPath)(value));
606
+ };
607
+ var createJsonPath = (path) => {
608
+ const candidatePath = path.map((p, i) => {
609
+ if (typeof p === "number") {
610
+ return `[${p}]`;
619
611
  } else {
620
- return yield* effect;
612
+ return i === 0 ? p : `.${p}`;
621
613
  }
614
+ }).join("");
615
+ invariant2(isJsonPath(candidatePath), `Invalid JsonPath: ${candidatePath}`, {
616
+ F: __dxlog_file3,
617
+ L: 69,
618
+ S: void 0,
619
+ A: [
620
+ "isJsonPath(candidatePath)",
621
+ "`Invalid JsonPath: ${candidatePath}`"
622
+ ]
623
+ });
624
+ return candidatePath;
625
+ };
626
+ var fromEffectValidationPath = (effectPath) => {
627
+ const jsonPath = effectPath.replace(/\.\[(\d+)\]/g, "[$1]");
628
+ invariant2(isJsonPath(jsonPath), `Invalid JsonPath: ${jsonPath}`, {
629
+ F: __dxlog_file3,
630
+ L: 80,
631
+ S: void 0,
632
+ A: [
633
+ "isJsonPath(jsonPath)",
634
+ "`Invalid JsonPath: ${jsonPath}`"
635
+ ]
622
636
  });
623
- TestHelpers2.provideTestContext = (effect, ctx) => Effect3.provideService(effect, TestContextService, ctx);
624
- })(TestHelpers || (TestHelpers = {}));
625
- var TestContextService = class extends Context2.Tag("@dxos/effect/TestContextService")() {
637
+ return jsonPath;
638
+ };
639
+ var splitJsonPath = (path) => {
640
+ if (!isJsonPath(path)) {
641
+ return [];
642
+ }
643
+ return path.match(/[a-zA-Z_$][\w$]*|\[\d+\]/g)?.map((part) => part.replace(/[[\]]/g, "")).map((part) => {
644
+ const parsed = Number.parseInt(part, 10);
645
+ return Number.isNaN(parsed) ? part : parsed;
646
+ }) ?? [];
647
+ };
648
+ var getField = (object, path) => {
649
+ return JSONPath({
650
+ path,
651
+ json: object
652
+ })[0];
653
+ };
654
+ var getValue = (obj, path) => {
655
+ return getDeep(obj, splitJsonPath(path));
656
+ };
657
+ var setValue = (obj, path, value) => {
658
+ return setDeep(obj, splitJsonPath(path), value);
626
659
  };
627
- var TestHelpers;
628
660
 
629
661
  // src/resource.ts
630
662
  import * as Effect4 from "effect/Effect";
631
663
  var acquireReleaseResource = (getResource) => Effect4.acquireRelease(Effect4.gen(function* () {
632
664
  const resource = getResource();
633
665
  yield* Effect4.promise(async () => {
634
- resource.open?.();
666
+ await resource.open?.();
635
667
  return void 0;
636
668
  });
637
669
  return resource;
638
670
  }), (resource) => Effect4.promise(async () => {
639
- resource.close?.();
671
+ await resource.close?.();
640
672
  return void 0;
641
673
  }));
674
+
675
+ // src/url.ts
676
+ import * as Function2 from "effect/Function";
677
+ import * as Option5 from "effect/Option";
678
+ import * as SchemaAST2 from "effect/SchemaAST";
679
+ import { decamelize } from "@dxos/util";
680
+ var ParamKeyAnnotationId = Symbol.for("@dxos/schema/annotation/ParamKey");
681
+ var getParamKeyAnnotation = SchemaAST2.getAnnotation(ParamKeyAnnotationId);
682
+ var ParamKeyAnnotation = (value) => (self) => self.annotations({
683
+ [ParamKeyAnnotationId]: value
684
+ });
685
+ var UrlParser = class {
686
+ _schema;
687
+ constructor(_schema) {
688
+ this._schema = _schema;
689
+ }
690
+ /**
691
+ * Parse URL params.
692
+ */
693
+ parse(_url) {
694
+ const url = new URL(_url);
695
+ return Object.entries(this._schema.fields).reduce((params, [key, type]) => {
696
+ let value = url.searchParams.get(decamelize(key));
697
+ if (value == null) {
698
+ value = url.searchParams.get(key);
699
+ }
700
+ if (value != null) {
701
+ if (SchemaAST2.isNumberKeyword(type.ast)) {
702
+ params[key] = parseInt(value);
703
+ } else if (SchemaAST2.isBooleanKeyword(type.ast)) {
704
+ params[key] = value === "true" || value === "1";
705
+ } else {
706
+ params[key] = value;
707
+ }
708
+ }
709
+ return params;
710
+ }, {});
711
+ }
712
+ /**
713
+ * Return URL with encoded params.
714
+ */
715
+ create(_url, params) {
716
+ const url = new URL(_url);
717
+ Object.entries(params).forEach(([key, value]) => {
718
+ if (value !== void 0) {
719
+ const field = this._schema.fields[key];
720
+ if (field) {
721
+ const { key: serializedKey } = Function2.pipe(getParamKeyAnnotation(field.ast), Option5.getOrElse(() => ({
722
+ key: decamelize(key)
723
+ })));
724
+ url.searchParams.set(serializedKey, String(value));
725
+ }
726
+ }
727
+ });
728
+ return url;
729
+ }
730
+ };
731
+
732
+ // src/RuntimeProvider.ts
733
+ var RuntimeProvider_exports = {};
734
+ __export(RuntimeProvider_exports, {
735
+ currentRuntime: () => currentRuntime,
736
+ provide: () => provide2,
737
+ runPromise: () => runPromise2
738
+ });
739
+ import * as Effect5 from "effect/Effect";
740
+ import * as Runtime3 from "effect/Runtime";
741
+ var currentRuntime = () => Effect5.runtime().pipe(Effect5.map(Effect5.succeed));
742
+ var runPromise2 = (provider) => async (effect) => {
743
+ const runtime2 = await runAndForwardErrors(provider);
744
+ return unwrapExit(await effect.pipe(Runtime3.runPromiseExit(runtime2)));
745
+ };
746
+ var provide2 = (runtimeProvider) => (effect) => Effect5.flatMap(runtimeProvider, (runtime2) => Effect5.provide(effect, runtime2));
642
747
  export {
748
+ dynamic_runtime_exports as DynamicRuntime,
643
749
  JsonPath,
644
750
  JsonProp,
645
751
  ParamKeyAnnotation,
646
- SimpleType,
647
- TestContextService,
648
- TestHelpers,
752
+ RuntimeProvider_exports as RuntimeProvider,
649
753
  UrlParser,
650
754
  VisitResult,
651
755
  acquireReleaseResource,
652
756
  causeToError,
653
757
  contextFromScope,
654
758
  createJsonPath,
759
+ createKvsStore,
655
760
  findAnnotation,
656
761
  findNode,
657
762
  findProperty,
658
763
  fromEffectValidationPath,
659
764
  getAnnotation2 as getAnnotation,
765
+ getArrayElementType,
766
+ getBaseType,
660
767
  getDiscriminatedType,
661
768
  getDiscriminatingProps,
662
769
  getField,
663
770
  getParamKeyAnnotation,
664
- getSimpleType,
771
+ getProperties,
665
772
  getValue,
666
773
  isArrayType,
667
774
  isDiscriminatedUnion,
668
775
  isJsonPath,
669
776
  isLiteralUnion,
777
+ isNestedType,
670
778
  isOption,
671
- isSimpleType,
779
+ isTupleType2 as isTupleType,
672
780
  mapAst,
673
781
  promiseWithCauseCapture,
674
782
  runAndForwardErrors,
783
+ runInRuntime,
675
784
  setValue,
676
785
  splitJsonPath,
677
786
  throwCause,