effect 4.0.0-beta.84 → 4.0.0-beta.85

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 (56) hide show
  1. package/dist/Context.d.ts.map +1 -1
  2. package/dist/Context.js +4 -3
  3. package/dist/Context.js.map +1 -1
  4. package/dist/Layer.js +4 -3
  5. package/dist/Layer.js.map +1 -1
  6. package/dist/LayerMap.d.ts.map +1 -1
  7. package/dist/LayerMap.js +4 -3
  8. package/dist/LayerMap.js.map +1 -1
  9. package/dist/Random.d.ts +31 -0
  10. package/dist/Random.d.ts.map +1 -1
  11. package/dist/Random.js +32 -0
  12. package/dist/Random.js.map +1 -1
  13. package/dist/Schema.d.ts +48 -6
  14. package/dist/Schema.d.ts.map +1 -1
  15. package/dist/Schema.js +31 -11
  16. package/dist/Schema.js.map +1 -1
  17. package/dist/SchemaAST.d.ts +8 -7
  18. package/dist/SchemaAST.d.ts.map +1 -1
  19. package/dist/SchemaAST.js +190 -131
  20. package/dist/SchemaAST.js.map +1 -1
  21. package/dist/internal/effect.js +10 -10
  22. package/dist/internal/effect.js.map +1 -1
  23. package/dist/internal/schema/arbitrary.js +17 -1
  24. package/dist/internal/schema/arbitrary.js.map +1 -1
  25. package/dist/internal/stackTraceLimit.d.ts +2 -0
  26. package/dist/internal/stackTraceLimit.d.ts.map +1 -0
  27. package/dist/internal/stackTraceLimit.js +40 -0
  28. package/dist/internal/stackTraceLimit.js.map +1 -0
  29. package/dist/internal/tracer.d.ts.map +1 -1
  30. package/dist/internal/tracer.js +4 -3
  31. package/dist/internal/tracer.js.map +1 -1
  32. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  33. package/dist/unstable/ai/Tool.js +4 -5
  34. package/dist/unstable/ai/Tool.js.map +1 -1
  35. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  36. package/dist/unstable/httpapi/HttpApiMiddleware.js +4 -3
  37. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  38. package/dist/unstable/persistence/PersistedQueue.js +1 -1
  39. package/dist/unstable/rpc/RpcMiddleware.d.ts.map +1 -1
  40. package/dist/unstable/rpc/RpcMiddleware.js +4 -3
  41. package/dist/unstable/rpc/RpcMiddleware.js.map +1 -1
  42. package/package.json +1 -1
  43. package/src/Context.ts +4 -5
  44. package/src/Layer.ts +4 -4
  45. package/src/LayerMap.ts +4 -3
  46. package/src/Random.ts +42 -0
  47. package/src/Schema.ts +75 -22
  48. package/src/SchemaAST.ts +217 -137
  49. package/src/internal/effect.ts +11 -11
  50. package/src/internal/schema/arbitrary.ts +23 -2
  51. package/src/internal/stackTraceLimit.ts +63 -0
  52. package/src/internal/tracer.ts +4 -3
  53. package/src/unstable/ai/Tool.ts +4 -3
  54. package/src/unstable/httpapi/HttpApiMiddleware.ts +4 -3
  55. package/src/unstable/persistence/PersistedQueue.ts +1 -1
  56. package/src/unstable/rpc/RpcMiddleware.ts +4 -3
@@ -382,6 +382,18 @@ function oneOf<T>(fc: typeof FastCheck, arbitraries: ReadonlyArray<FastCheck.Arb
382
382
  return arbitraries.length === 0 ? undefined : arbitraries.length === 1 ? arbitraries[0] : fc.oneof(...arbitraries)
383
383
  }
384
384
 
385
+ const finiteNumberConstraint: Constraint = {
386
+ noInfinity: true,
387
+ noNaN: true
388
+ }
389
+
390
+ function finiteNumberContext(ctx: Context): Context {
391
+ return {
392
+ ...ctx,
393
+ constraint: finiteNumberConstraint
394
+ }
395
+ }
396
+
385
397
  function reportChecks(report: MutableReport, checks: SchemaAST.Checks | undefined, path: ReadonlyArray<PropertyKey>) {
386
398
  function visit(check: SchemaAST.Check<any>, covered: boolean) {
387
399
  const arbitrary = check.annotations?.arbitrary
@@ -430,6 +442,9 @@ export function collectReport(ast: SchemaAST.AST, report: MutableReport) {
430
442
  case "Union":
431
443
  ast.types.forEach((type) => visit(type, path))
432
444
  break
445
+ case "TemplateLiteral":
446
+ ast.parts.forEach((part, i) => visit(SchemaAST.toEncoded(part), [...path, i]))
447
+ break
433
448
  case "Suspend":
434
449
  visit(ast.thunk(), path)
435
450
  break
@@ -605,8 +620,14 @@ function base(ast: SchemaAST.AST, path: ReadonlyArray<PropertyKey>): LazyArbitra
605
620
  return same((fc) => fc.oneof(fc.object(), fc.array(fc.anything())))
606
621
  case "Enum":
607
622
  return recur(SchemaAST.enumsToLiterals(ast), path)
608
- case "TemplateLiteral":
609
- return same((fc) => fc.stringMatching(SchemaAST.getTemplateLiteralRegExp(ast)))
623
+ case "TemplateLiteral": {
624
+ const parts = ast.parts.map((part, i) => recur(SchemaAST.toEncoded(part), [...path, i]))
625
+ return same((fc, ctx, recursionStack) =>
626
+ fc.tuple(...parts.map((part) => part(fc, finiteNumberContext(ctx), recursionStack))).map((segments) =>
627
+ segments.map((segment) => globalThis.String(segment)).join("")
628
+ )
629
+ )
630
+ }
610
631
  case "Arrays": {
611
632
  const elements = ast.elements.map((ast, i) => ({
612
633
  ast,
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Utility for safely manipulating `Error.stackTraceLimit` in environments
3
+ * where intrinsics may be frozen (e.g., SES / hardened JavaScript or
4
+ * deterministic sandboxes such as Temporal). When the property is non-writable,
5
+ * mutating it throws, so all manipulation here degrades to a best-effort,
6
+ * silent no-op.
7
+ *
8
+ * Mirrors the guard Node uses internally:
9
+ * https://github.com/nodejs/node/blob/e77694631f1642c302f664703197b5aabc65b482/lib/internal/errors.js#L246
10
+ *
11
+ * The error is constructed inline at each call site (rather than inside a
12
+ * closure here) so the captured stack trace keeps pointing at the real caller
13
+ * instead of this module.
14
+ *
15
+ * @internal
16
+ */
17
+ import type { ErrorWithStackTraceLimit } from "./tracer.ts"
18
+
19
+ const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
20
+ const ObjectPrototypeHasOwnProperty = Object.prototype.hasOwnProperty
21
+ const ObjectIsExtensible = Object.isExtensible
22
+
23
+ /**
24
+ * Check if `Error.stackTraceLimit` is writable.
25
+ * Returns `false` if the property is frozen, non-writable, or `Error` is non-extensible.
26
+ *
27
+ * @internal
28
+ */
29
+ export const isStackTraceLimitWritable = (): boolean => {
30
+ const desc = ObjectGetOwnPropertyDescriptor(Error, "stackTraceLimit")
31
+ if (desc === undefined) {
32
+ return ObjectIsExtensible(Error)
33
+ }
34
+
35
+ return ObjectPrototypeHasOwnProperty.call(desc, "writable")
36
+ ? desc.writable === true
37
+ : desc.set !== undefined
38
+ }
39
+
40
+ // Cache the check result since it won't change during runtime
41
+ const canWriteStackTraceLimit = isStackTraceLimitWritable()
42
+
43
+ /**
44
+ * Get the current `Error.stackTraceLimit` value.
45
+ * Returns `undefined` if the property doesn't exist.
46
+ *
47
+ * @internal
48
+ */
49
+ export const getStackTraceLimit = (): number | undefined => (Error as ErrorWithStackTraceLimit).stackTraceLimit
50
+
51
+ /**
52
+ * Safely set `Error.stackTraceLimit` if possible, otherwise no-op.
53
+ *
54
+ * Accepts `undefined` so a value read via {@link getStackTraceLimit} can be
55
+ * restored faithfully.
56
+ *
57
+ * @internal
58
+ */
59
+ export const setStackTraceLimit = (value: number | undefined): void => {
60
+ if (canWriteStackTraceLimit) {
61
+ ;(Error as ErrorWithStackTraceLimit).stackTraceLimit = value
62
+ }
63
+ }
@@ -1,4 +1,5 @@
1
1
  import type * as Tracer from "../Tracer.ts"
2
+ import { getStackTraceLimit, setStackTraceLimit } from "./stackTraceLimit.ts"
2
3
 
3
4
  export interface ErrorWithStackTraceLimit {
4
5
  stackTraceLimit?: number | undefined
@@ -13,10 +14,10 @@ export const addSpanStackTrace = <A extends Tracer.TraceOptions>(
13
14
  } else if (options?.captureStackTrace !== undefined && typeof options.captureStackTrace !== "boolean") {
14
15
  return options
15
16
  }
16
- const limit = (Error as ErrorWithStackTraceLimit).stackTraceLimit
17
- ;(Error as ErrorWithStackTraceLimit).stackTraceLimit = 3
17
+ const limit = getStackTraceLimit()
18
+ setStackTraceLimit(3)
18
19
  const traceError = new Error()
19
- ;(Error as ErrorWithStackTraceLimit).stackTraceLimit = limit
20
+ setStackTraceLimit(limit)
20
21
  return {
21
22
  ...options,
22
23
  captureStackTrace: spanCleaner(() => traceError.stack)
@@ -14,6 +14,7 @@
14
14
  import * as Context from "../../Context.ts"
15
15
  import type * as Effect from "../../Effect.ts"
16
16
  import { constFalse, constTrue, identity } from "../../Function.ts"
17
+ import * as StackTraceLimit from "../../internal/stackTraceLimit.ts"
17
18
  import type * as JsonSchema from "../../JsonSchema.ts"
18
19
  import { pipeArguments } from "../../Pipeable.ts"
19
20
  import * as Predicate from "../../Predicate.ts"
@@ -1997,12 +1998,12 @@ function filter(obj: any) {
1997
1998
  */
1998
1999
  export const unsafeSecureJsonParse = (text: string): unknown => {
1999
2000
  // Performance optimization, see https://github.com/fastify/secure-json-parse/pull/90
2000
- const { stackTraceLimit } = Error
2001
- Error.stackTraceLimit = 0
2001
+ const prevLimit = StackTraceLimit.getStackTraceLimit()
2002
+ StackTraceLimit.setStackTraceLimit(0)
2002
2003
  try {
2003
2004
  return _parse(text)
2004
2005
  } finally {
2005
- Error.stackTraceLimit = stackTraceLimit
2006
+ StackTraceLimit.setStackTraceLimit(prevLimit)
2006
2007
  }
2007
2008
  }
2008
2009
 
@@ -15,6 +15,7 @@
15
15
  /** @effect-diagnostics classSelfMismatch:off */
16
16
  import * as Context from "../../Context.ts"
17
17
  import * as Effect from "../../Effect.ts"
18
+ import { getStackTraceLimit, setStackTraceLimit } from "../../internal/stackTraceLimit.ts"
18
19
  import * as Layer from "../../Layer.ts"
19
20
  import { hasProperty } from "../../Predicate.ts"
20
21
  import type * as Schema from "../../Schema.ts"
@@ -352,10 +353,10 @@ export const Service = <
352
353
  } | undefined
353
354
  ) => {
354
355
  const Err = globalThis.Error as any
355
- const limit = Err.stackTraceLimit
356
- Err.stackTraceLimit = 2
356
+ const limit = getStackTraceLimit()
357
+ setStackTraceLimit(2)
357
358
  const creationError = new Err()
358
- Err.stackTraceLimit = limit
359
+ setStackTraceLimit(limit)
359
360
 
360
361
  class Service extends Context.Service<Self, any>()(id) {}
361
362
  const self = Service as any
@@ -508,7 +508,7 @@ export const makeStoreRedis = Effect.fnUntraced(function*(
508
508
  id,
509
509
  JSON.stringify({ id, element, attempts: 0 })
510
510
  )
511
- : redis.send("LPUSH", `${prefix}${name}`, JSON.stringify({ id, element, attempts: 0 })),
511
+ : redis.send("RPUSH", `${prefix}${name}`, JSON.stringify({ id, element, attempts: 0 })),
512
512
  ({ cause }) =>
513
513
  new PersistedQueueError({
514
514
  message: "Failed to offer element to persisted queue",
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import * as Context from "../../Context.ts"
13
13
  import * as Effect from "../../Effect.ts"
14
+ import { getStackTraceLimit, setStackTraceLimit } from "../../internal/stackTraceLimit.ts"
14
15
  import * as Layer from "../../Layer.ts"
15
16
  import * as Schema from "../../Schema.ts"
16
17
  import { Scope } from "../../Scope.ts"
@@ -292,10 +293,10 @@ export const Service = <
292
293
  }
293
294
  ) => {
294
295
  const Err = globalThis.Error as any
295
- const limit = Err.stackTraceLimit
296
- Err.stackTraceLimit = 2
296
+ const limit = getStackTraceLimit()
297
+ setStackTraceLimit(2)
297
298
  const creationError = new Err()
298
- Err.stackTraceLimit = limit
299
+ setStackTraceLimit(limit)
299
300
 
300
301
  function ServiceClass() {}
301
302
  const ServiceClass_ = ServiceClass as any as Mutable<AnyService>