bonsai-js 1.0.0 → 1.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/CHANGELOG.md +11 -0
- package/README.md +24 -4
- package/dist/artifact.d.mts +47 -0
- package/dist/artifact.mjs +139 -0
- package/dist/artifact.mjs.map +1 -0
- package/dist/check/bind.mjs +117 -0
- package/dist/check/bind.mjs.map +1 -0
- package/dist/check/checker.mjs +14 -116
- package/dist/check/checker.mjs.map +1 -1
- package/dist/compile/compiler.mjs +2 -3
- package/dist/compile/compiler.mjs.map +1 -1
- package/dist/declared.mjs +8 -1
- package/dist/declared.mjs.map +1 -1
- package/dist/digest.mjs +109 -0
- package/dist/digest.mjs.map +1 -0
- package/dist/environment.d.mts +1 -1
- package/dist/environment.mjs +52 -309
- package/dist/environment.mjs.map +1 -1
- package/dist/errors.d.mts +21 -2
- package/dist/errors.mjs +17 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/features.mjs +3 -3
- package/dist/features.mjs.map +1 -1
- package/dist/functions/builtins.mjs +2 -2
- package/dist/functions/define.mjs +13 -6
- package/dist/functions/define.mjs.map +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +3 -2
- package/dist/lite/index.d.mts +3 -2
- package/dist/lite/index.mjs +3 -2
- package/dist/lite/index.mjs.map +1 -1
- package/dist/load.mjs +308 -0
- package/dist/load.mjs.map +1 -0
- package/dist/program.mjs +323 -0
- package/dist/program.mjs.map +1 -0
- package/dist/query/index.mjs +1 -1
- package/dist/runtime/index.d.mts +61 -0
- package/dist/runtime/index.mjs +95 -0
- package/dist/runtime/index.mjs.map +1 -0
- package/dist/service/index.mjs +8 -5
- package/dist/service/index.mjs.map +1 -1
- package/dist/syntax/parser.mjs +1 -1
- package/dist/syntax/printer.mjs +1 -1
- package/dist/types.mjs +103 -23
- package/dist/types.mjs.map +1 -1
- package/dist/version.mjs +7 -0
- package/dist/version.mjs.map +1 -0
- package/package.json +10 -2
package/dist/features.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features.mjs","names":[],"sources":["../src/features.ts"],"sourcesContent":["/**\n * Explaining and partial evaluation: the program features the main entry\n * point adds to every environment. `bonsai-js/lite` leaves them out, so a\n * bundle that only checks and evaluates does not carry them.\n */\nimport { analyze, type Analysis, type CallPlan } from './check/checker.js'\nimport { compileProgram, type CompiledProgram } from './compile/compiler.js'\nimport { escaping, isOwn, raised } from './runtime/attribution.js'\nimport { BonsaiRuntimeError, type BonsaiError } from './errors.js'\nimport { describeMismatch, type Out, type ValidationBudget } from './functions/define.js'\nimport {\n EVALUATE_OPTION_KEYS,\n contextOf,\n evaluationLimits,\n hostDataFailure,\n invalidContext,\n isValidDate,\n validationBudget,\n type EvaluateOptions,\n type ExplainOptions,\n type Explanation,\n type Features,\n type ProgramCore,\n type ProgramFeatures,\n} from './environment.js'\nimport {\n forTranslation,\n partiallyEvaluate,\n residualTexts,\n type PartialOptions,\n type PartialResult,\n} from './partial.js'\nimport { isStackOverflow, tooDeep } from './runtime/overflow.js'\nimport { State } from './runtime/state.js'\nimport {\n DEFAULT_MAX_ITERATIONS,\n DEFAULT_MAX_TRACE_NODES,\n SNAPSHOT_ENTRIES,\n Tracer,\n freezeAll,\n reasonsOf,\n renderTrace,\n snapshot,\n snapshotTrace,\n type ExplanationJSON,\n type Parts,\n} from './runtime/trace.js'\nimport { isMap, keyListCost } from './runtime/values.js'\nimport { forEachChild, type CallNode, type Node } from './syntax/ast.js'\nimport { BLOCKED_NAMES, isName } from './syntax/lexer.js'\nimport type { Type } from './types.js'\n\n/** Subtrees compiled for partial evaluation, in nodes, kept per program: this times its own. */\nconst SUBTREE_CACHE_FACTOR = 2\n\nconst EXPLAIN_OPTION_KEYS: ReadonlySet<string> = new Set([\n ...EVALUATE_OPTION_KEYS,\n 'maxIterations',\n 'maxTraceNodes',\n 'exhaustive',\n])\n\ninterface ExplainSettings {\n readonly maxIterations: number\n readonly maxNodes: number\n readonly exhaustive: boolean\n /** The evaluation options among them, validated by evaluationLimits. */\n readonly evaluate: EvaluateOptions | undefined\n}\n\n/** Reads explain options once, with the same TypeError/RangeError rules as evaluate's. */\nfunction explainSettings(options: unknown): ExplainSettings {\n if (options === undefined) {\n return {\n maxIterations: DEFAULT_MAX_ITERATIONS,\n maxNodes: DEFAULT_MAX_TRACE_NODES,\n exhaustive: false,\n evaluate: undefined,\n }\n }\n if (typeof options !== 'object' || options === null || Array.isArray(options))\n throw new TypeError('Explain options must be an object')\n let copy: Record<string, unknown>\n try {\n copy = { ...(options as Record<string, unknown>) }\n } catch {\n throw new TypeError('Explain options could not be read')\n }\n for (const key of Object.keys(copy)) {\n if (!EXPLAIN_OPTION_KEYS.has(key)) {\n throw new TypeError(\n `Unknown explain option key \"${key}\" (expected one of: ${[...EXPLAIN_OPTION_KEYS].join(', ')})`,\n )\n }\n }\n const count = (name: string, fallback: number): number => {\n const value = copy[name]\n if (value === undefined) return fallback\n if (typeof value !== 'number') throw new TypeError(`Explain option \"${name}\" must be a number`)\n if (!Number.isSafeInteger(value) || value < 0)\n throw new RangeError(`Explain option \"${name}\" must be a non-negative integer`)\n return value\n }\n if (copy.exhaustive !== undefined && typeof copy.exhaustive !== 'boolean')\n throw new TypeError('Explain option \"exhaustive\" must be a boolean')\n const {\n maxIterations: _iterations,\n maxTraceNodes: _nodes,\n exhaustive: _exhaustive,\n ...evaluate\n } = copy\n return {\n maxIterations: count('maxIterations', DEFAULT_MAX_ITERATIONS),\n maxNodes: count('maxTraceNodes', DEFAULT_MAX_TRACE_NODES),\n exhaustive: copy.exhaustive === true,\n evaluate,\n }\n}\n\nconst PARTIAL_OPTION_KEYS: ReadonlySet<string> = new Set([\n 'unknown',\n 'callHostFunctions',\n 'now',\n 'maxSteps',\n 'timeout',\n 'signal',\n])\n/** A variable name, then field names as reads spell them: none empty or blocked. */\nconst isPath = (path: unknown): boolean => {\n if (typeof path !== 'string') return false\n const [name, ...fields] = path.split('.')\n return isName(name) && fields.every((field) => field !== '' && !BLOCKED_NAMES.has(field))\n}\n\n/** Reads partial() options once, with the same TypeError rules as the other options. */\nfunction partialOptions(options: unknown): PartialOptions {\n if (options === undefined) return {}\n if (typeof options !== 'object' || options === null || Array.isArray(options))\n throw new TypeError('Partial options must be an object')\n let copy: Record<string, unknown>\n try {\n copy = { ...(options as Record<string, unknown>) }\n if (Array.isArray(copy.unknown)) copy.unknown = [...(copy.unknown as unknown[])]\n } catch {\n throw new TypeError('Partial options could not be read')\n }\n for (const key of Object.keys(copy)) {\n if (!PARTIAL_OPTION_KEYS.has(key)) {\n throw new TypeError(\n `Unknown partial option key \"${key}\" (expected one of: ${[...PARTIAL_OPTION_KEYS].join(', ')})`,\n )\n }\n }\n const unknown = copy.unknown\n if (unknown !== undefined && (!Array.isArray(unknown) || !unknown.every(isPath)))\n throw new TypeError('Partial option \"unknown\" must be a list of variable names or dotted paths')\n if (copy.callHostFunctions !== undefined && typeof copy.callHostFunctions !== 'boolean')\n throw new TypeError('Partial option \"callHostFunctions\" must be a boolean')\n if (copy.now !== undefined && !isValidDate(copy.now))\n throw new TypeError('Partial option \"now\" must be a valid Date')\n return copy\n}\n\n/** Paths listed as unknown, as a tree of segments: `whole` marks a listed path. */\ninterface UnknownTree {\n whole: boolean\n readonly next: Map<string, UnknownTree>\n}\n\nfunction unknownTree(paths: readonly string[]): UnknownTree {\n const root: UnknownTree = { whole: false, next: new Map() }\n for (const path of paths) {\n let node = root\n for (const segment of path.split('.')) {\n let child = node.next.get(segment)\n if (child === undefined) node.next.set(segment, (child = { whole: false, next: new Map() }))\n node = child\n }\n node.whole = true\n }\n return root\n}\n\n/**\n * Why `value` does not conform to `type`, leaving out the parts of it under\n * listed unknown paths (`skip`): those are incomplete by design. Everything\n * else is checked as evaluation checks a context.\n */\nfunction describeKnown(\n value: unknown,\n type: Type,\n path: string,\n skip: UnknownTree | undefined,\n budget: ValidationBudget,\n): string | undefined {\n if (skip === undefined) return describeMismatch(value, type, path, budget)\n if (skip.whole) return undefined\n if (type.kind === 'union') {\n let first: string | undefined\n for (const member of type.types) {\n const problem = describeKnown(value, member, path, skip, budget)\n if (problem === undefined) return undefined\n first ??= problem\n }\n return first\n }\n const actual = value === undefined ? null : value\n if (type.kind !== 'map' || !isMap(actual)) return describeMismatch(value, type, path, budget)\n if (--budget.remaining < 0) budget.onExhausted('steps')\n for (const [key, fieldType] of Object.entries(type.fields)) {\n const field = Object.hasOwn(actual, key) ? actual[key] : null\n const problem = describeKnown(field, fieldType, `${path}.${key}`, skip.next.get(key), budget)\n if (problem !== undefined) return problem\n }\n if (type.rest === undefined) return undefined\n const keys = Object.keys(actual)\n budget.remaining -= keyListCost(keys.length)\n if (budget.remaining < 0) budget.onExhausted('steps')\n for (const key of keys) {\n // As evaluation's validation: keys the language never reads, or that hold undefined, are not data.\n if (Object.hasOwn(type.fields, key) || BLOCKED_NAMES.has(key) || actual[key] === undefined)\n continue\n const problem = describeKnown(\n actual[key],\n type.rest,\n `${path}.${key}`,\n skip.next.get(key),\n budget,\n )\n if (problem !== undefined) return problem\n }\n return undefined\n}\n\nfunction programFeatures<Ctx, R>(core: ProgramCore<R>): ProgramFeatures<Ctx, R> {\n const {\n source,\n analysis,\n expect,\n settings,\n checkEnv,\n compileOptions,\n residualOf,\n prepare,\n checked,\n settle,\n } = core\n\n let traceSync: CompiledProgram | undefined\n let traceAsync: CompiledProgram | undefined\n\n function explanation(\n tracer: Tracer,\n outcome: { ok: true; value: R } | { ok: false; error: BonsaiError },\n ): Explanation<R> {\n const trace = tracer.finish()\n // A result refused after the run (a promise-like value, a failed `expect`\n // check) is the whole expression's failure: marked on the root.\n if (!outcome.ok && trace.evaluated && trace.error === undefined) {\n trace.error = { code: outcome.error.code, message: outcome.error.message }\n delete trace.value\n }\n const truncated = tracer.truncated\n // Every rendering of this explanation lists a map's keys once, however it is sliced.\n const { listings } = tracer\n // Taken once, the first time any part is serialized: one budget for the\n // whole snapshot, however often a value recurs or the traces are sliced.\n let json: ExplanationJSON | undefined\n const parts: Parts = new WeakMap()\n const toJSON = (): ExplanationJSON => {\n if (json !== undefined) return json\n const budget = { left: SNAPSHOT_ENTRIES, keys: listings }\n const result = outcome.ok\n ? { ok: true as const, value: snapshot(outcome.value, budget) }\n : { ok: false as const, error: outcome.error.toJSON() }\n // Frozen: every serialization (and every part of it) is this same snapshot.\n return (json = freezeAll({\n ...result,\n truncated,\n trace: snapshotTrace(trace, budget, parts),\n }))\n }\n tracer.parts = () => (toJSON(), parts)\n return Object.freeze({\n ...outcome,\n trace,\n truncated,\n reasons: () => reasonsOf(trace, listings),\n toString: () => renderTrace(trace, truncated, listings),\n toJSON,\n })\n }\n\n function failure(error: unknown): { ok: false; error: BonsaiError } {\n return { ok: false, error: escaping(hostDataFailure(error, source)) }\n }\n\n // A residual's nodes keep the original's offsets (or none, for known\n // values), so their text comes from the printed residual instead: mapped\n // once, the first time the residual is explained.\n let residualText: ReadonlyMap<Node, string> | undefined\n const residualTextMap = (printed: string): ReadonlyMap<Node, string> =>\n (residualText ??= residualTexts(analysis.root, printed, {\n maxSourceLength: Math.max(settings.parseLimits.maxSourceLength, printed.length),\n // Printing adds parentheses (and unary minus for negative literals).\n maxDepth: settings.parseLimits.maxDepth * 4,\n maxNodes: settings.parseLimits.maxNodes * 4,\n }))\n const textOfResidual =\n residualOf === undefined\n ? undefined\n : (node: Node): string => residualTextMap(residualOf.source).get(node) ?? ''\n\n function tracerFor(explain: ExplainSettings): Tracer {\n return new Tracer(\n source,\n analysis.root,\n explain.maxIterations,\n explain.maxNodes,\n explain.exhaustive,\n textOfResidual,\n )\n }\n\n /** With `promised`, a thenable result fails as evaluate() fails it (see settle). */\n function explainSync(\n context: unknown,\n options: ExplainOptions | undefined,\n promised = false,\n ): Explanation<R> {\n const explain = explainSettings(options)\n if (analysis.async) {\n return explanation(\n tracerFor(explain),\n failure(\n raised(\n new BonsaiRuntimeError(\n 'ASYNC_IN_SYNC',\n 'This expression calls an async function; use explain() instead of explainSync()',\n { source },\n ),\n ),\n ),\n )\n }\n const code = (traceSync ??= compileProgram(analysis, 'sync', {\n ...compileOptions,\n trace: true,\n }))\n const limits = evaluationLimits(explain.evaluate, settings)\n const ctx = contextOf(context)\n const state = new State(settings.runtimeLimits, settings.clock)\n // A residual's text is mapped once per residual, work its partial()\n // already charged, so explaining costs the steps evaluating does.\n let tracer: Tracer | undefined\n try {\n prepare(state, ctx, limits, code.localCount)\n tracer = tracerFor(explain)\n state.tracer = tracer\n const value = code.run(state) as R\n checked(value, state)\n state.checkTime()\n if (promised) settle(value)\n return explanation(tracer, { ok: true, value })\n } catch (error) {\n return explanation(tracer ?? tracerFor(explain), failure(error))\n } finally {\n state.release()\n }\n }\n\n async function explainAsync(\n context: unknown,\n options: ExplainOptions | undefined,\n ): Promise<Explanation<R>> {\n if (!analysis.async) return explainSync(context, options, true)\n const explain = explainSettings(options)\n const code = (traceAsync ??= compileProgram(analysis, 'async', {\n ...compileOptions,\n trace: true,\n }))\n const limits = evaluationLimits(explain.evaluate, settings)\n const ctx = contextOf(context)\n const state = new State(settings.runtimeLimits, settings.clock)\n let tracer: Tracer | undefined\n try {\n prepare(state, ctx, limits, code.localCount)\n tracer = tracerFor(explain)\n state.tracer = tracer\n const value = ((await code.run(state)) as Out).v as R\n // In evaluate()'s order: the expected type, the deadline, then a promise-like value.\n checked(value, state)\n state.checkTime()\n settle(value)\n return explanation(tracer, { ok: true, value })\n } catch (error) {\n return explanation(tracer ?? tracerFor(explain), failure(error))\n } finally {\n state.release()\n }\n }\n\n // Each call the original program checked, by its source span and name. A\n // residual keeps the spans of the calls it copies, so it can run each one\n // with the overloads the original chose from the declared types: checking\n // the residual again would see other types (a known branch removed, an\n // open environment) and could pick another overload.\n let callsBySpan: Map<string, CallPlan | null> | undefined\n const callKey = (call: CallNode): string => `${call.start}:${call.end}:${call.name}`\n\n function originalPlans(\n compiled: Node,\n checkedCalls: ReadonlyMap<CallNode, CallPlan>,\n ): ReadonlyMap<CallNode, CallPlan> {\n if (callsBySpan === undefined) {\n callsBySpan = new Map()\n for (const [call, plan] of analysis.calls) {\n const key = callKey(call)\n // Two calls with one span cannot be told apart; neither is reused.\n callsBySpan.set(key, callsBySpan.has(key) ? null : plan)\n }\n }\n const bySpan = callsBySpan\n const plans = new Map(checkedCalls)\n const visit = (node: Node): void => {\n if (node.type === 'Call') {\n const plan = bySpan.get(callKey(node))\n if (plan !== undefined && plan !== null) plans.set(node, plan)\n }\n forEachChild(node, visit)\n }\n visit(compiled)\n return plans\n }\n\n // Sub-trees compiled on their own for partial evaluation, by free locals.\n // Which subtrees are closed depends on the data, so the cache holds at most\n // a few times the program's own nodes, and starts over when full.\n let subtrees = new Map<Node, Map<string, CompiledProgram>>()\n let subtreeNodes = 0\n\n function partial(\n known: Record<string, unknown>,\n rawOptions: unknown,\n translation = false,\n ): PartialResult<Ctx, R> {\n const options = partialOptions(rawOptions)\n // One budget for the whole partial evaluation, validated as evaluation's is.\n const limits = evaluationLimits(\n { maxSteps: options.maxSteps, timeout: options.timeout, signal: options.signal },\n settings,\n )\n const context = contextOf(known)\n const now = options.now\n const state = new State(settings.runtimeLimits, now === undefined ? settings.clock : () => now)\n state.reset(context, source, 0, limits.maxSteps, limits.timeout, limits.signal)\n try {\n // Known variables are validated as evaluation validates them, all but\n // the parts under listed unknown paths (incomplete by design): all the\n // data a residual has folded in is checked here, once.\n if (settings.validateContext && settings.variables !== undefined) {\n const variables = settings.variables\n const skip = unknownTree(options.unknown ?? [])\n try {\n const budget = validationBudget(source, {\n maxDepth: settings.runtimeLimits.maxValueDepth,\n maxSteps: limits.maxSteps,\n timeout: limits.timeout,\n })\n for (const [name, type] of Object.entries(variables)) {\n if (!Object.hasOwn(context, name)) continue\n const problem = describeKnown(context[name], type, name, skip.next.get(name), budget)\n invalidContext(problem, source)\n }\n } catch (error) {\n // Validation only reads the known data, so any other failure is the host's.\n if (!isOwn(error)) throw hostDataFailure(error, source)\n if (error instanceof BonsaiRuntimeError) return { status: 'error', error }\n throw error\n }\n }\n const result = partiallyEvaluate<R>(\n {\n analysis,\n hostKind: (name) => {\n const def = settings.host.get(name)\n return def === undefined\n ? undefined\n : { async: def.async === true, call: def.call === true }\n },\n charge: (steps = 1) => {\n state.charge(steps)\n },\n checkTime: () => {\n state.checkTime()\n },\n listLimit: (length, at) => {\n state.listLimit(length, at)\n },\n // Translation reads the residual tree, never its printed source.\n maxSourceLength: translation ? Infinity : settings.parseLimits.maxSourceLength,\n readKnown: (read) => {\n try {\n return read()\n } catch (error) {\n throw hostDataFailure(error, source)\n }\n },\n evaluate: (node, locals, size, total) => {\n const key = locals.map(([name]) => name).join('\\u0000')\n let code = subtrees.get(node)?.get(key)\n if (code === undefined) {\n if (subtreeNodes + size > SUBTREE_CACHE_FACTOR * total) {\n subtrees = new Map()\n subtreeNodes = 0\n }\n code = compileProgram({ ...analysis, root: node }, 'sync', {\n locals: locals.map(([name]) => name),\n })\n let byLocals = subtrees.get(node)\n if (byLocals === undefined) subtrees.set(node, (byLocals = new Map()))\n byLocals.set(key, code)\n subtreeNodes += size\n }\n state.ensureLocals(code.localCount)\n locals.forEach(([, value], slot) => {\n state.locals[slot] = value\n })\n try {\n return code.run(state)\n } catch (error) {\n throw hostDataFailure(error, source)\n }\n },\n evaluateFolded: (node, origin, locals) => {\n const plan = origin.type === 'Call' ? analysis.calls.get(origin) : undefined\n const code = compileProgram(\n {\n ...analysis,\n root: node,\n calls: plan === undefined ? new Map() : new Map([[node as CallNode, plan]]),\n },\n 'sync',\n { locals: locals.map(([name]) => name) },\n )\n state.ensureLocals(code.localCount)\n locals.forEach(([, value], slot) => {\n state.locals[slot] = value\n })\n try {\n return code.run(state)\n } catch (error) {\n throw hostDataFailure(error, source)\n }\n },\n compileResidual: (\n residual,\n bindings,\n residualSource,\n readsContext,\n knownRoots,\n dependsOn,\n ) => {\n // The original expression passed the checker; inlining known\n // values can make a failing branch statically visible, and that\n // failure must happen at run time, as it would have, so findings\n // here do not stop compilation. Analyzed as a tree (not\n // re-parsed), so the printer's parentheses cannot push it past\n // the parse depth limit.\n const reanalyzed: Analysis = analyze(\n residual,\n { ...checkEnv, variables: undefined, strict: false },\n { expected: expect },\n )\n return core.residual(\n // The plans go on the calls of the tree that is compiled: the\n // analysis root, where implicit lambdas are explicit nodes.\n { ...reanalyzed, calls: originalPlans(reanalyzed.root, reanalyzed.calls) },\n new Map(Object.entries(bindings)),\n {\n source: residualSource,\n readsContext,\n knownRoots,\n dependsOn,\n shapes: state.shapes,\n },\n )\n },\n },\n context,\n options,\n )\n // A decided result still has to match `expect`, as evaluation would check it.\n if (result.status === 'value') {\n try {\n checked(result.value, state)\n } catch (error) {\n // Checking reads the value, which can be host data.\n if (!isOwn(error)) throw hostDataFailure(error, source)\n if (error instanceof BonsaiRuntimeError) return { status: 'error', error }\n throw error\n }\n }\n // The residual accepts any object at run time; its parameter is typed by this program's context.\n return result as PartialResult<Ctx, R>\n } catch (error) {\n // Host data is read through readKnown, evaluate, and the checks above,\n // which report its failures as HOST_ERROR; anything else is a failure\n // of the engine itself, not of the caller's data, so it is not relabeled.\n if (isStackOverflow(error)) throw tooDeep(source, error)\n throw error\n } finally {\n state.release()\n }\n }\n\n return {\n explainSync,\n explainAsync,\n partial(program, known, options) {\n const translation = forTranslation(program)\n let result: PartialResult<Ctx, R>\n try {\n result = partial(known as Record<string, unknown>, options, translation)\n } catch (error) {\n throw escaping(error)\n }\n if (result.status === 'error') escaping(result.error)\n return Object.freeze(result)\n },\n }\n}\n\n/** Explaining and partial evaluation, for the main entry point's environments. */\nexport const explainAndPartial: Features = { program: programFeatures }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features.mjs","names":[],"sources":["../src/features.ts"],"sourcesContent":["/**\n * Explaining and partial evaluation: the program features the main entry\n * point adds to every environment. `bonsai-js/lite` leaves them out, so a\n * bundle that only checks and evaluates does not carry them.\n */\nimport { analyze, type Analysis, type CallPlan } from './check/checker.js'\nimport { compileProgram, type CompiledProgram } from './compile/compiler.js'\nimport { escaping, isOwn, raised } from './runtime/attribution.js'\nimport { BonsaiRuntimeError, type BonsaiError } from './errors.js'\nimport { describeMismatch, type Out, type ValidationBudget } from './functions/define.js'\nimport {\n EVALUATE_OPTION_KEYS,\n contextOf,\n evaluationLimits,\n hostDataFailure,\n invalidContext,\n isValidDate,\n validationBudget,\n} from './program.js'\nimport {\n type EvaluateOptions,\n type ExplainOptions,\n type Explanation,\n type Features,\n type ProgramCore,\n type ProgramFeatures,\n} from './environment.js'\nimport {\n forTranslation,\n partiallyEvaluate,\n residualTexts,\n type PartialOptions,\n type PartialResult,\n} from './partial.js'\nimport { isStackOverflow, tooDeep } from './runtime/overflow.js'\nimport { State } from './runtime/state.js'\nimport {\n DEFAULT_MAX_ITERATIONS,\n DEFAULT_MAX_TRACE_NODES,\n SNAPSHOT_ENTRIES,\n Tracer,\n freezeAll,\n reasonsOf,\n renderTrace,\n snapshot,\n snapshotTrace,\n type ExplanationJSON,\n type Parts,\n} from './runtime/trace.js'\nimport { isMap, keyListCost } from './runtime/values.js'\nimport { forEachChild, type CallNode, type Node } from './syntax/ast.js'\nimport { BLOCKED_NAMES, isName } from './syntax/lexer.js'\nimport type { Type } from './types.js'\n\n/** Subtrees compiled for partial evaluation, in nodes, kept per program: this times its own. */\nconst SUBTREE_CACHE_FACTOR = 2\n\nconst EXPLAIN_OPTION_KEYS: ReadonlySet<string> = new Set([\n ...EVALUATE_OPTION_KEYS,\n 'maxIterations',\n 'maxTraceNodes',\n 'exhaustive',\n])\n\ninterface ExplainSettings {\n readonly maxIterations: number\n readonly maxNodes: number\n readonly exhaustive: boolean\n /** The evaluation options among them, validated by evaluationLimits. */\n readonly evaluate: EvaluateOptions | undefined\n}\n\n/** Reads explain options once, with the same TypeError/RangeError rules as evaluate's. */\nfunction explainSettings(options: unknown): ExplainSettings {\n if (options === undefined) {\n return {\n maxIterations: DEFAULT_MAX_ITERATIONS,\n maxNodes: DEFAULT_MAX_TRACE_NODES,\n exhaustive: false,\n evaluate: undefined,\n }\n }\n if (typeof options !== 'object' || options === null || Array.isArray(options))\n throw new TypeError('Explain options must be an object')\n let copy: Record<string, unknown>\n try {\n copy = { ...(options as Record<string, unknown>) }\n } catch {\n throw new TypeError('Explain options could not be read')\n }\n for (const key of Object.keys(copy)) {\n if (!EXPLAIN_OPTION_KEYS.has(key)) {\n throw new TypeError(\n `Unknown explain option key \"${key}\" (expected one of: ${[...EXPLAIN_OPTION_KEYS].join(', ')})`,\n )\n }\n }\n const count = (name: string, fallback: number): number => {\n const value = copy[name]\n if (value === undefined) return fallback\n if (typeof value !== 'number') throw new TypeError(`Explain option \"${name}\" must be a number`)\n if (!Number.isSafeInteger(value) || value < 0)\n throw new RangeError(`Explain option \"${name}\" must be a non-negative integer`)\n return value\n }\n if (copy.exhaustive !== undefined && typeof copy.exhaustive !== 'boolean')\n throw new TypeError('Explain option \"exhaustive\" must be a boolean')\n const {\n maxIterations: _iterations,\n maxTraceNodes: _nodes,\n exhaustive: _exhaustive,\n ...evaluate\n } = copy\n return {\n maxIterations: count('maxIterations', DEFAULT_MAX_ITERATIONS),\n maxNodes: count('maxTraceNodes', DEFAULT_MAX_TRACE_NODES),\n exhaustive: copy.exhaustive === true,\n evaluate,\n }\n}\n\nconst PARTIAL_OPTION_KEYS: ReadonlySet<string> = new Set([\n 'unknown',\n 'callHostFunctions',\n 'now',\n 'maxSteps',\n 'timeout',\n 'signal',\n])\n/** A variable name, then field names as reads spell them: none empty or blocked. */\nconst isPath = (path: unknown): boolean => {\n if (typeof path !== 'string') return false\n const [name, ...fields] = path.split('.')\n return isName(name) && fields.every((field) => field !== '' && !BLOCKED_NAMES.has(field))\n}\n\n/** Reads partial() options once, with the same TypeError rules as the other options. */\nfunction partialOptions(options: unknown): PartialOptions {\n if (options === undefined) return {}\n if (typeof options !== 'object' || options === null || Array.isArray(options))\n throw new TypeError('Partial options must be an object')\n let copy: Record<string, unknown>\n try {\n copy = { ...(options as Record<string, unknown>) }\n if (Array.isArray(copy.unknown)) copy.unknown = [...(copy.unknown as unknown[])]\n } catch {\n throw new TypeError('Partial options could not be read')\n }\n for (const key of Object.keys(copy)) {\n if (!PARTIAL_OPTION_KEYS.has(key)) {\n throw new TypeError(\n `Unknown partial option key \"${key}\" (expected one of: ${[...PARTIAL_OPTION_KEYS].join(', ')})`,\n )\n }\n }\n const unknown = copy.unknown\n if (unknown !== undefined && (!Array.isArray(unknown) || !unknown.every(isPath)))\n throw new TypeError('Partial option \"unknown\" must be a list of variable names or dotted paths')\n if (copy.callHostFunctions !== undefined && typeof copy.callHostFunctions !== 'boolean')\n throw new TypeError('Partial option \"callHostFunctions\" must be a boolean')\n if (copy.now !== undefined && !isValidDate(copy.now))\n throw new TypeError('Partial option \"now\" must be a valid Date')\n return copy\n}\n\n/** Paths listed as unknown, as a tree of segments: `whole` marks a listed path. */\ninterface UnknownTree {\n whole: boolean\n readonly next: Map<string, UnknownTree>\n}\n\nfunction unknownTree(paths: readonly string[]): UnknownTree {\n const root: UnknownTree = { whole: false, next: new Map() }\n for (const path of paths) {\n let node = root\n for (const segment of path.split('.')) {\n let child = node.next.get(segment)\n if (child === undefined) node.next.set(segment, (child = { whole: false, next: new Map() }))\n node = child\n }\n node.whole = true\n }\n return root\n}\n\n/**\n * Why `value` does not conform to `type`, leaving out the parts of it under\n * listed unknown paths (`skip`): those are incomplete by design. Everything\n * else is checked as evaluation checks a context.\n */\nfunction describeKnown(\n value: unknown,\n type: Type,\n path: string,\n skip: UnknownTree | undefined,\n budget: ValidationBudget,\n): string | undefined {\n if (skip === undefined) return describeMismatch(value, type, path, budget)\n if (skip.whole) return undefined\n if (type.kind === 'union') {\n let first: string | undefined\n for (const member of type.types) {\n const problem = describeKnown(value, member, path, skip, budget)\n if (problem === undefined) return undefined\n first ??= problem\n }\n return first\n }\n const actual = value === undefined ? null : value\n if (type.kind !== 'map' || !isMap(actual)) return describeMismatch(value, type, path, budget)\n if (--budget.remaining < 0) budget.onExhausted('steps')\n for (const [key, fieldType] of Object.entries(type.fields)) {\n const field = Object.hasOwn(actual, key) ? actual[key] : null\n const problem = describeKnown(field, fieldType, `${path}.${key}`, skip.next.get(key), budget)\n if (problem !== undefined) return problem\n }\n if (type.rest === undefined) return undefined\n const keys = Object.keys(actual)\n budget.remaining -= keyListCost(keys.length)\n if (budget.remaining < 0) budget.onExhausted('steps')\n for (const key of keys) {\n // As evaluation's validation: keys the language never reads, or that hold undefined, are not data.\n if (Object.hasOwn(type.fields, key) || BLOCKED_NAMES.has(key) || actual[key] === undefined)\n continue\n const problem = describeKnown(\n actual[key],\n type.rest,\n `${path}.${key}`,\n skip.next.get(key),\n budget,\n )\n if (problem !== undefined) return problem\n }\n return undefined\n}\n\nfunction programFeatures<Ctx, R>(core: ProgramCore<R>): ProgramFeatures<Ctx, R> {\n const {\n source,\n analysis,\n expect,\n settings,\n checkEnv,\n compileOptions,\n residualOf,\n prepare,\n checked,\n settle,\n } = core\n\n let traceSync: CompiledProgram | undefined\n let traceAsync: CompiledProgram | undefined\n\n function explanation(\n tracer: Tracer,\n outcome: { ok: true; value: R } | { ok: false; error: BonsaiError },\n ): Explanation<R> {\n const trace = tracer.finish()\n // A result refused after the run (a promise-like value, a failed `expect`\n // check) is the whole expression's failure: marked on the root.\n if (!outcome.ok && trace.evaluated && trace.error === undefined) {\n trace.error = { code: outcome.error.code, message: outcome.error.message }\n delete trace.value\n }\n const truncated = tracer.truncated\n // Every rendering of this explanation lists a map's keys once, however it is sliced.\n const { listings } = tracer\n // Taken once, the first time any part is serialized: one budget for the\n // whole snapshot, however often a value recurs or the traces are sliced.\n let json: ExplanationJSON | undefined\n const parts: Parts = new WeakMap()\n const toJSON = (): ExplanationJSON => {\n if (json !== undefined) return json\n const budget = { left: SNAPSHOT_ENTRIES, keys: listings }\n const result = outcome.ok\n ? { ok: true as const, value: snapshot(outcome.value, budget) }\n : { ok: false as const, error: outcome.error.toJSON() }\n // Frozen: every serialization (and every part of it) is this same snapshot.\n return (json = freezeAll({\n ...result,\n truncated,\n trace: snapshotTrace(trace, budget, parts),\n }))\n }\n tracer.parts = () => (toJSON(), parts)\n return Object.freeze({\n ...outcome,\n trace,\n truncated,\n reasons: () => reasonsOf(trace, listings),\n toString: () => renderTrace(trace, truncated, listings),\n toJSON,\n })\n }\n\n function failure(error: unknown): { ok: false; error: BonsaiError } {\n return { ok: false, error: escaping(hostDataFailure(error, source)) }\n }\n\n // A residual's nodes keep the original's offsets (or none, for known\n // values), so their text comes from the printed residual instead: mapped\n // once, the first time the residual is explained.\n let residualText: ReadonlyMap<Node, string> | undefined\n const residualTextMap = (printed: string): ReadonlyMap<Node, string> =>\n (residualText ??= residualTexts(analysis.root, printed, {\n maxSourceLength: Math.max(settings.parseLimits.maxSourceLength, printed.length),\n // Printing adds parentheses (and unary minus for negative literals).\n maxDepth: settings.parseLimits.maxDepth * 4,\n maxNodes: settings.parseLimits.maxNodes * 4,\n }))\n const textOfResidual =\n residualOf === undefined\n ? undefined\n : (node: Node): string => residualTextMap(residualOf.source).get(node) ?? ''\n\n function tracerFor(explain: ExplainSettings): Tracer {\n return new Tracer(\n source,\n analysis.root,\n explain.maxIterations,\n explain.maxNodes,\n explain.exhaustive,\n textOfResidual,\n )\n }\n\n /** With `promised`, a thenable result fails as evaluate() fails it (see settle). */\n function explainSync(\n context: unknown,\n options: ExplainOptions | undefined,\n promised = false,\n ): Explanation<R> {\n const explain = explainSettings(options)\n if (analysis.async) {\n return explanation(\n tracerFor(explain),\n failure(\n raised(\n new BonsaiRuntimeError(\n 'ASYNC_IN_SYNC',\n 'This expression calls an async function; use explain() instead of explainSync()',\n { source },\n ),\n ),\n ),\n )\n }\n const code = (traceSync ??= compileProgram(analysis, 'sync', {\n ...compileOptions,\n trace: true,\n }))\n const limits = evaluationLimits(explain.evaluate, settings)\n const ctx = contextOf(context)\n const state = new State(settings.runtimeLimits, settings.clock)\n // A residual's text is mapped once per residual, work its partial()\n // already charged, so explaining costs the steps evaluating does.\n let tracer: Tracer | undefined\n try {\n prepare(state, ctx, limits, code.localCount)\n tracer = tracerFor(explain)\n state.tracer = tracer\n const value = code.run(state) as R\n checked(value, state)\n state.checkTime()\n if (promised) settle(value)\n return explanation(tracer, { ok: true, value })\n } catch (error) {\n return explanation(tracer ?? tracerFor(explain), failure(error))\n } finally {\n state.release()\n }\n }\n\n async function explainAsync(\n context: unknown,\n options: ExplainOptions | undefined,\n ): Promise<Explanation<R>> {\n if (!analysis.async) return explainSync(context, options, true)\n const explain = explainSettings(options)\n const code = (traceAsync ??= compileProgram(analysis, 'async', {\n ...compileOptions,\n trace: true,\n }))\n const limits = evaluationLimits(explain.evaluate, settings)\n const ctx = contextOf(context)\n const state = new State(settings.runtimeLimits, settings.clock)\n let tracer: Tracer | undefined\n try {\n prepare(state, ctx, limits, code.localCount)\n tracer = tracerFor(explain)\n state.tracer = tracer\n const value = ((await code.run(state)) as Out).v as R\n // In evaluate()'s order: the expected type, the deadline, then a promise-like value.\n checked(value, state)\n state.checkTime()\n settle(value)\n return explanation(tracer, { ok: true, value })\n } catch (error) {\n return explanation(tracer ?? tracerFor(explain), failure(error))\n } finally {\n state.release()\n }\n }\n\n // Each call the original program checked, by its source span and name. A\n // residual keeps the spans of the calls it copies, so it can run each one\n // with the overloads the original chose from the declared types: checking\n // the residual again would see other types (a known branch removed, an\n // open environment) and could pick another overload.\n let callsBySpan: Map<string, CallPlan | null> | undefined\n const callKey = (call: CallNode): string => `${call.start}:${call.end}:${call.name}`\n\n function originalPlans(\n compiled: Node,\n checkedCalls: ReadonlyMap<CallNode, CallPlan>,\n ): ReadonlyMap<CallNode, CallPlan> {\n if (callsBySpan === undefined) {\n callsBySpan = new Map()\n for (const [call, plan] of analysis.calls) {\n const key = callKey(call)\n // Two calls with one span cannot be told apart; neither is reused.\n callsBySpan.set(key, callsBySpan.has(key) ? null : plan)\n }\n }\n const bySpan = callsBySpan\n const plans = new Map(checkedCalls)\n const visit = (node: Node): void => {\n if (node.type === 'Call') {\n const plan = bySpan.get(callKey(node))\n if (plan !== undefined && plan !== null) plans.set(node, plan)\n }\n forEachChild(node, visit)\n }\n visit(compiled)\n return plans\n }\n\n // Sub-trees compiled on their own for partial evaluation, by free locals.\n // Which subtrees are closed depends on the data, so the cache holds at most\n // a few times the program's own nodes, and starts over when full.\n let subtrees = new Map<Node, Map<string, CompiledProgram>>()\n let subtreeNodes = 0\n\n function partial(\n known: Record<string, unknown>,\n rawOptions: unknown,\n translation = false,\n ): PartialResult<Ctx, R> {\n const options = partialOptions(rawOptions)\n // One budget for the whole partial evaluation, validated as evaluation's is.\n const limits = evaluationLimits(\n { maxSteps: options.maxSteps, timeout: options.timeout, signal: options.signal },\n settings,\n )\n const context = contextOf(known)\n const now = options.now\n const state = new State(settings.runtimeLimits, now === undefined ? settings.clock : () => now)\n state.reset(context, source, 0, limits.maxSteps, limits.timeout, limits.signal)\n try {\n // Known variables are validated as evaluation validates them, all but\n // the parts under listed unknown paths (incomplete by design): all the\n // data a residual has folded in is checked here, once.\n if (settings.validateContext && settings.variables !== undefined) {\n const variables = settings.variables\n const skip = unknownTree(options.unknown ?? [])\n try {\n const budget = validationBudget(source, {\n maxDepth: settings.runtimeLimits.maxValueDepth,\n maxSteps: limits.maxSteps,\n timeout: limits.timeout,\n })\n for (const [name, type] of Object.entries(variables)) {\n if (!Object.hasOwn(context, name)) continue\n const problem = describeKnown(context[name], type, name, skip.next.get(name), budget)\n invalidContext(problem, source)\n }\n } catch (error) {\n // Validation only reads the known data, so any other failure is the host's.\n if (!isOwn(error)) throw hostDataFailure(error, source)\n if (error instanceof BonsaiRuntimeError) return { status: 'error', error }\n throw error\n }\n }\n const result = partiallyEvaluate<R>(\n {\n analysis,\n hostKind: (name) => {\n const def = settings.host.get(name)\n return def === undefined\n ? undefined\n : { async: def.async === true, call: def.call === true }\n },\n charge: (steps = 1) => {\n state.charge(steps)\n },\n checkTime: () => {\n state.checkTime()\n },\n listLimit: (length, at) => {\n state.listLimit(length, at)\n },\n // Translation reads the residual tree, never its printed source.\n maxSourceLength: translation ? Infinity : settings.parseLimits.maxSourceLength,\n readKnown: (read) => {\n try {\n return read()\n } catch (error) {\n throw hostDataFailure(error, source)\n }\n },\n evaluate: (node, locals, size, total) => {\n const key = locals.map(([name]) => name).join('\\u0000')\n let code = subtrees.get(node)?.get(key)\n if (code === undefined) {\n if (subtreeNodes + size > SUBTREE_CACHE_FACTOR * total) {\n subtrees = new Map()\n subtreeNodes = 0\n }\n code = compileProgram({ ...analysis, root: node }, 'sync', {\n locals: locals.map(([name]) => name),\n })\n let byLocals = subtrees.get(node)\n if (byLocals === undefined) subtrees.set(node, (byLocals = new Map()))\n byLocals.set(key, code)\n subtreeNodes += size\n }\n state.ensureLocals(code.localCount)\n locals.forEach(([, value], slot) => {\n state.locals[slot] = value\n })\n try {\n return code.run(state)\n } catch (error) {\n throw hostDataFailure(error, source)\n }\n },\n evaluateFolded: (node, origin, locals) => {\n const plan = origin.type === 'Call' ? analysis.calls.get(origin) : undefined\n const code = compileProgram(\n {\n ...analysis,\n root: node,\n calls: plan === undefined ? new Map() : new Map([[node as CallNode, plan]]),\n },\n 'sync',\n { locals: locals.map(([name]) => name) },\n )\n state.ensureLocals(code.localCount)\n locals.forEach(([, value], slot) => {\n state.locals[slot] = value\n })\n try {\n return code.run(state)\n } catch (error) {\n throw hostDataFailure(error, source)\n }\n },\n compileResidual: (\n residual,\n bindings,\n residualSource,\n readsContext,\n knownRoots,\n dependsOn,\n ) => {\n // The original expression passed the checker; inlining known\n // values can make a failing branch statically visible, and that\n // failure must happen at run time, as it would have, so findings\n // here do not stop compilation. Analyzed as a tree (not\n // re-parsed), so the printer's parentheses cannot push it past\n // the parse depth limit.\n const reanalyzed: Analysis = analyze(\n residual,\n { ...checkEnv, variables: undefined, strict: false },\n { expected: expect },\n )\n return core.residual(\n // The plans go on the calls of the tree that is compiled: the\n // analysis root, where implicit lambdas are explicit nodes.\n { ...reanalyzed, calls: originalPlans(reanalyzed.root, reanalyzed.calls) },\n new Map(Object.entries(bindings)),\n {\n source: residualSource,\n readsContext,\n knownRoots,\n dependsOn,\n shapes: state.shapes,\n },\n )\n },\n },\n context,\n options,\n )\n // A decided result still has to match `expect`, as evaluation would check it.\n if (result.status === 'value') {\n try {\n checked(result.value, state)\n } catch (error) {\n // Checking reads the value, which can be host data.\n if (!isOwn(error)) throw hostDataFailure(error, source)\n if (error instanceof BonsaiRuntimeError) return { status: 'error', error }\n throw error\n }\n }\n // The residual accepts any object at run time; its parameter is typed by this program's context.\n return result as PartialResult<Ctx, R>\n } catch (error) {\n // Host data is read through readKnown, evaluate, and the checks above,\n // which report its failures as HOST_ERROR; anything else is a failure\n // of the engine itself, not of the caller's data, so it is not relabeled.\n if (isStackOverflow(error)) throw tooDeep(source, error)\n throw error\n } finally {\n state.release()\n }\n }\n\n return {\n explainSync,\n explainAsync,\n partial(program, known, options) {\n const translation = forTranslation(program)\n let result: PartialResult<Ctx, R>\n try {\n result = partial(known as Record<string, unknown>, options, translation)\n } catch (error) {\n throw escaping(error)\n }\n if (result.status === 'error') escaping(result.error)\n return Object.freeze(result)\n },\n }\n}\n\n/** Explaining and partial evaluation, for the main entry point's environments. */\nexport const explainAndPartial: Features = { program: programFeatures }\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BLOCKED_NAMES } from "../syntax/lexer.mjs";
|
|
2
|
-
import { RegexSyntaxError, compileRegex, searchRegex } from "../runtime/regex.mjs";
|
|
3
2
|
import { Duration, MS_PER_DAY, MS_PER_HOUR, MS_PER_MINUTE, MS_PER_SECOND, MS_PER_WEEK, chargeIndexKey, chargeKey, chargeSearch, contains, dateTime, describeKind, durationOf, equals, errorText, holdsKey, isMap, isTimestamp, isValidDuration, keyListCost, kindOf, mapBuildCost, order, shown, sortOrder, timeOf, toText, track } from "../runtime/values.mjs";
|
|
4
|
-
import { addDays, addMonths, checkDatePattern, checked, formatTimestamp, fromWallClock, isoWeekday, parseTimestamp, wallClock } from "../runtime/time.mjs";
|
|
5
3
|
import { isExact, t, unionOf, widen } from "../types.mjs";
|
|
6
4
|
import { K, Out, T, U, define, fnType, overload } from "./define.mjs";
|
|
5
|
+
import { RegexSyntaxError, compileRegex, searchRegex } from "../runtime/regex.mjs";
|
|
6
|
+
import { addDays, addMonths, checkDatePattern, checked, formatTimestamp, fromWallClock, isoWeekday, parseTimestamp, wallClock } from "../runtime/time.mjs";
|
|
7
7
|
//#region src/functions/builtins.ts
|
|
8
8
|
/** What toNumber accepts: an optional sign, digits with an optional fraction, and an optional exponent. */
|
|
9
9
|
const DECIMAL_TEXT = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/u;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BLOCKED_NAMES } from "../syntax/lexer.mjs";
|
|
2
2
|
import { Duration, isMap, isTimestamp, isValidDuration, keyListCost, shown } from "../runtime/values.mjs";
|
|
3
|
-
import { formatType } from "../types.mjs";
|
|
3
|
+
import { formatType, typeText } from "../types.mjs";
|
|
4
4
|
//#region src/functions/define.ts
|
|
5
5
|
/**
|
|
6
6
|
* What async evaluation resolves to: a value in a box. JavaScript adopts (runs
|
|
@@ -32,6 +32,13 @@ function fnType(params, result) {
|
|
|
32
32
|
result
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
+
/** An overload's signature as messages and hovers show it, e.g. `slice(string, number, number?): string`. */
|
|
36
|
+
function signatureText(name, candidate) {
|
|
37
|
+
const required = candidate.required ?? candidate.params.length;
|
|
38
|
+
const params = candidate.params.map((param, i) => `${typeText(param)}${i >= required ? "?" : ""}`);
|
|
39
|
+
if (candidate.rest !== void 0) params.push(`...${typeText(candidate.rest)}`);
|
|
40
|
+
return `${name}(${params.join(", ")}): ${typeText(candidate.result)}`;
|
|
41
|
+
}
|
|
35
42
|
/** Whether parameter `index` of any overload is function-typed (lambda position). */
|
|
36
43
|
function isLambdaPosition(def, index) {
|
|
37
44
|
return def.overloads.some((candidate) => candidate.params[index]?.kind === "function");
|
|
@@ -96,7 +103,9 @@ function conforms(value, type, state, depth = 0) {
|
|
|
96
103
|
}
|
|
97
104
|
return true;
|
|
98
105
|
}
|
|
99
|
-
case "union":
|
|
106
|
+
case "union":
|
|
107
|
+
state.charge(type.types.length);
|
|
108
|
+
return type.types.some((member) => conforms(value, member, state, depth));
|
|
100
109
|
case "timestamp": return isTimestamp(value);
|
|
101
110
|
case "duration": return isValidDuration(value);
|
|
102
111
|
default: return matchesKind(value, type);
|
|
@@ -210,9 +219,7 @@ function assertType(value, path, depth = 0) {
|
|
|
210
219
|
return;
|
|
211
220
|
case "union":
|
|
212
221
|
if (!Array.isArray(value.types)) throw new TypeError(`${path}.types must be an array`);
|
|
213
|
-
value.types.
|
|
214
|
-
assertType(member, `${path}.types[${i}]`, depth + 1);
|
|
215
|
-
});
|
|
222
|
+
for (let i = 0; i < value.types.length; i++) assertType(value.types[i], `${path}.types[${i}]`, depth + 1);
|
|
216
223
|
return;
|
|
217
224
|
case "opaque":
|
|
218
225
|
if (typeof value.name !== "string") throw new TypeError(`${path} is an opaque type without a name`);
|
|
@@ -260,6 +267,6 @@ function assertHostSpec(spec, label) {
|
|
|
260
267
|
if (typeof spec.run !== "function") throw new TypeError(`${label} needs a run function`);
|
|
261
268
|
}
|
|
262
269
|
//#endregion
|
|
263
|
-
export { K, Out, T, U, assertHostSpec, assertType, conforms, define, describeMismatch, fnType, isItemLambdaPosition, isLambdaPosition, isRecord, matchesKind, overload };
|
|
270
|
+
export { K, Out, T, U, assertHostSpec, assertType, conforms, define, describeMismatch, fnType, isItemLambdaPosition, isLambdaPosition, isRecord, matchesKind, overload, signatureText };
|
|
264
271
|
|
|
265
272
|
//# sourceMappingURL=define.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.mjs","names":[],"sources":["../../src/functions/define.ts"],"sourcesContent":["import { BLOCKED_NAMES } from '../syntax/lexer.js'\nimport type { Span } from '../errors.js'\nimport type { State } from '../runtime/state.js'\nimport {\n Duration,\n isMap,\n isTimestamp,\n isValidDuration,\n keyListCost,\n shown,\n} from '../runtime/values.js'\nimport { formatType, type FunctionType, type Type, type TypeVar } from '../types.js'\n\n/** A lambda as seen by a built-in: called with the item and its index. */\nexport type Lambda = (item: unknown, index: number) => unknown\n\n/** Call-site information handed to a built-in implementation. */\nexport interface CallSite {\n readonly state: State\n readonly span: Span\n}\n\n/**\n * What async evaluation resolves to: a value in a box. JavaScript adopts (runs\n * `then` on) any thenable an async function returns or awaits, and data from\n * the host is opaque, never awaited, so values cross an `await` boxed.\n */\nexport class Out {\n readonly v: unknown\n constructor(v: unknown) {\n this.v = v\n }\n}\n\nexport interface Overload {\n /** Parameter types. Function-typed parameters take lambdas. */\n readonly params: readonly Type[]\n /** How many leading parameters are required (default: all). */\n readonly required?: number\n /** Type of any further arguments (variadic). */\n readonly rest?: Type\n /** Result type; may reference type variables bound by the parameters. */\n readonly result: Type\n readonly run: (args: unknown[], site: CallSite) => unknown\n /**\n * Variant used when a lambda argument is asynchronous. Its lambdas resolve\n * to an {@link Out}, and so does it.\n */\n readonly runAsync?: ((args: unknown[], site: CallSite) => Promise<Out>) | undefined\n /** Type variables that must bind to one orderable kind (number, string, timestamp, duration). */\n readonly ordered?: readonly string[]\n /**\n * Static validation of literal arguments (undefined where an argument is\n * not a literal). Returns an error message, so mistakes in constant\n * patterns are reported when the expression is checked.\n */\n readonly literals?: ((values: readonly unknown[]) => string | undefined) | undefined\n}\n\nexport interface FunctionDef {\n readonly name: string\n readonly description: string\n readonly overloads: readonly Overload[]\n /** Host functions: returns a promise and must be awaited. */\n readonly async?: boolean\n /** Host functions: receives a HostCall (context and signal) as its first argument. */\n readonly call?: boolean\n readonly host?: boolean\n /** Host functions: steps charged per call (default 32). */\n readonly cost?: number\n}\n\nexport const T: TypeVar = Object.freeze({ kind: 'var', name: 'T' })\nexport const U: TypeVar = Object.freeze({ kind: 'var', name: 'U' })\nexport const K: TypeVar = Object.freeze({ kind: 'var', name: 'K' })\n\nexport function fnType(params: readonly Type[], result: Type): FunctionType {\n return Object.freeze({ kind: 'function', params: Object.freeze([...params]), result })\n}\n\n/** Whether parameter `index` of any overload is function-typed (lambda position). */\nexport function isLambdaPosition(def: FunctionDef, index: number): boolean {\n return def.overloads.some((candidate) => candidate.params[index]?.kind === 'function')\n}\n\n/**\n * Whether `.` may stand for the lambda at `index`: its first parameter must be\n * the current item (the element of the list argument). In reduce it is the\n * accumulator, so `.` there would silently mean the wrong value.\n */\nexport function isItemLambdaPosition(def: FunctionDef, index: number): boolean {\n return def.overloads.some((candidate) => {\n const lambda = candidate.params[index]\n const items = candidate.params[0]\n if (lambda?.kind !== 'function' || items?.kind !== 'list') return false\n const first = lambda.params[0]\n const element = items.element\n return (\n first === element ||\n (first?.kind === 'var' && element.kind === 'var' && first.name === element.name)\n )\n })\n}\n\n/** Shallow runtime test used to pick an overload by argument kinds. */\nexport function matchesKind(value: unknown, type: Type): boolean {\n switch (type.kind) {\n case 'any':\n case 'var':\n return true\n case 'never':\n return false\n case 'null':\n return value === null || value === undefined\n case 'boolean':\n return typeof value === 'boolean'\n case 'number':\n return typeof value === 'number'\n case 'string':\n return typeof value === 'string'\n case 'literal':\n return value === type.value\n case 'list':\n return Array.isArray(value)\n case 'map':\n return isMap(value)\n case 'timestamp':\n return value instanceof Date\n case 'duration':\n return isValidDuration(value)\n case 'union':\n return type.types.some((member) => matchesKind(value, member))\n case 'opaque':\n return (\n value !== null &&\n value !== undefined &&\n (typeof value === 'function' ||\n typeof value === 'symbol' ||\n typeof value === 'bigint' ||\n typeof value === 'object')\n )\n case 'function':\n default:\n return typeof value === 'function'\n }\n}\n\n/** Deep runtime conformance, used to guard host function parameters. */\nexport function conforms(value: unknown, type: Type, state: State, depth = 0): boolean {\n if (depth > state.limits.maxValueDepth) return false\n switch (type.kind) {\n case 'list': {\n if (!Array.isArray(value)) return false\n if (type.element.kind === 'any') return true\n state.charge(value.length)\n // oxlint-disable-next-line typescript/prefer-for-of -- indexing never invokes a host array's own Symbol.iterator\n for (let i = 0; i < value.length; i++)\n if (!conforms(value[i], type.element, state, depth + 1)) return false\n return true\n }\n case 'map': {\n if (!isMap(value)) return false\n const fields = Object.entries(type.fields)\n state.charge(1 + fields.length)\n for (const [key, fieldType] of fields) {\n if (!conforms(Object.hasOwn(value, key) ? value[key] : null, fieldType, state, depth + 1))\n return false\n }\n if (type.rest !== undefined && type.rest.kind !== 'any') {\n const keys = Object.keys(value)\n state.charge(keyListCost(keys.length))\n for (const key of keys) {\n // A key holding undefined is absent (see holdsKey).\n const field = value[key]\n if (\n field !== undefined &&\n !Object.hasOwn(type.fields, key) &&\n !conforms(field, type.rest, state, depth + 1)\n )\n return false\n }\n }\n return true\n }\n case 'union':\n return type.types.some((member) => conforms(value, member, state, depth))\n case 'timestamp':\n // An invalid Date is an opaque host value, not a timestamp.\n return isTimestamp(value)\n case 'duration':\n return isValidDuration(value)\n case 'any':\n case 'boolean':\n case 'function':\n case 'literal':\n case 'never':\n case 'null':\n case 'number':\n case 'opaque':\n case 'string':\n case 'var':\n default:\n return matchesKind(value, type)\n }\n}\n\nconst CLOCK_SAMPLE = 1024\n\nfunction describeValue(value: unknown): string {\n if (value === null) return 'null (missing)'\n if (Array.isArray(value)) return 'a list'\n if (value instanceof Date) return isTimestamp(value) ? 'a timestamp' : 'an invalid Date'\n if (value instanceof Duration && !isValidDuration(value)) return 'an invalid Duration'\n if (typeof value === 'object') return 'a map'\n if (typeof value === 'string') return `string ${shown(value)}`\n if (typeof value === 'number' || typeof value === 'boolean')\n return `${typeof value} ${String(value)}`\n return typeof value\n}\n\n/** Bounds context validation like evaluation: depth, work, and wall-clock time. */\nexport interface ValidationBudget {\n readonly maxDepth: number\n remaining: number\n readonly deadline: number\n readonly onExhausted: (reason: 'steps' | 'time' | 'depth') => never\n}\n\n/** Why `value` does not conform to `type` (naming the path), or undefined when it does. */\nexport function describeMismatch(\n value: unknown,\n type: Type,\n path: string,\n budget: ValidationBudget,\n depth = 0,\n): string | undefined {\n if (depth > budget.maxDepth) budget.onExhausted('depth')\n if (--budget.remaining < 0) budget.onExhausted('steps')\n if (\n budget.deadline !== 0 &&\n budget.remaining % CLOCK_SAMPLE === 0 &&\n performance.now() > budget.deadline\n ) {\n budget.onExhausted('time')\n }\n const actual = value === undefined ? null : value\n if (type.kind === 'list' && Array.isArray(actual)) {\n for (let i = 0; i < actual.length; i++) {\n const problem = describeMismatch(actual[i], type.element, `${path}[${i}]`, budget, depth + 1)\n if (problem !== undefined) return problem\n }\n return undefined\n }\n if (type.kind === 'map' && isMap(actual)) {\n for (const [key, fieldType] of Object.entries(type.fields)) {\n const field = Object.hasOwn(actual, key) ? actual[key] : null\n const problem = describeMismatch(field, fieldType, `${path}.${key}`, budget, depth + 1)\n if (problem !== undefined) return problem\n }\n if (type.rest !== undefined) {\n const keys = Object.keys(actual)\n // Listing a map's keys costs per key (see keyListCost), and more for a large one.\n budget.remaining -= keyListCost(keys.length)\n if (budget.remaining < 0) budget.onExhausted('steps')\n for (const key of keys) {\n // Keys the language can never read, or that hold undefined, are not part of the data.\n if (Object.hasOwn(type.fields, key) || BLOCKED_NAMES.has(key) || actual[key] === undefined)\n continue\n const problem = describeMismatch(\n actual[key],\n type.rest,\n `${path}.${key}`,\n budget,\n depth + 1,\n )\n if (problem !== undefined) return problem\n }\n }\n return undefined\n }\n if (type.kind === 'union') {\n if (\n type.types.some(\n (member) => describeMismatch(actual, member, path, budget, depth) === undefined,\n )\n ) {\n return undefined\n }\n } else if (type.kind === 'timestamp') {\n if (isTimestamp(actual)) return undefined\n } else if (type.kind === 'duration') {\n if (isValidDuration(actual)) return undefined\n } else if (type.kind === 'number') {\n // The language has no NaN or infinities, so a context holding one is not data it can read.\n if (typeof actual === 'number' && Number.isFinite(actual)) return undefined\n } else if (type.kind !== 'list' && type.kind !== 'map' && matchesKind(actual, type)) {\n return undefined\n }\n return `${path} should be ${formatType(type)}, got ${describeValue(actual)}`\n}\n\nexport function overload(\n params: readonly Type[],\n result: Type,\n run: Overload['run'],\n options: {\n required?: number\n rest?: Type\n runAsync?: Overload['runAsync']\n ordered?: readonly string[]\n literals?: Overload['literals']\n } = {},\n): Overload {\n return Object.freeze({ params: Object.freeze([...params]), result, run, ...options })\n}\n\nexport function define(\n name: string,\n description: string,\n overloads: readonly Overload[],\n): FunctionDef {\n return Object.freeze({ name, description, overloads: Object.freeze([...overloads]) })\n}\n\n// === validation of host-supplied declarations ===\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nfunction describe(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'an array'\n return typeof value\n}\n\nconst TYPE_DEPTH_LIMIT = 64\n\n/**\n * Throws a TypeError unless `value` is a well-formed Type (as built by `t`).\n * Types come from configuration, so a malformed one is a programming error.\n */\nexport function assertType(value: unknown, path: string, depth = 0): asserts value is Type {\n if (depth > TYPE_DEPTH_LIMIT) throw new TypeError(`${path} nests deeper than ${TYPE_DEPTH_LIMIT}`)\n if (!isRecord(value) || typeof value.kind !== 'string') {\n throw new TypeError(`${path} must be a type built with t (got ${describe(value)})`)\n }\n switch (value.kind) {\n case 'any':\n case 'never':\n case 'null':\n case 'boolean':\n case 'number':\n case 'string':\n case 'timestamp':\n case 'duration':\n return\n case 'literal':\n if (!['string', 'number', 'boolean'].includes(typeof value.value)) {\n throw new TypeError(\n `${path} is a literal type whose value is not a string, number, or boolean`,\n )\n }\n if (typeof value.value === 'number' && !Number.isFinite(value.value))\n throw new TypeError(`${path} is a literal type whose number is not finite`)\n return\n case 'list':\n assertType(value.element, `${path}.element`, depth + 1)\n return\n case 'map':\n if (!isRecord(value.fields)) throw new TypeError(`${path}.fields must be an object`)\n for (const [key, field] of Object.entries(value.fields))\n assertType(field, `${path}.fields.${key}`, depth + 1)\n if (value.rest !== undefined) assertType(value.rest, `${path}.rest`, depth + 1)\n return\n case 'union':\n if (!Array.isArray(value.types)) throw new TypeError(`${path}.types must be an array`)\n value.types.forEach((member: unknown, i: number) => {\n assertType(member, `${path}.types[${i}]`, depth + 1)\n })\n return\n case 'opaque':\n if (typeof value.name !== 'string')\n throw new TypeError(`${path} is an opaque type without a name`)\n return\n case 'function':\n case 'var':\n default:\n throw new TypeError(`${path} has an unsupported type kind \"${value.kind}\"`)\n }\n}\n\nconst HOST_SPEC_KEYS = new Set([\n 'params',\n 'returns',\n 'required',\n 'rest',\n 'async',\n 'call',\n 'description',\n 'cost',\n 'run',\n])\n\n/**\n * Throws unless `spec` is a well-formed host function declaration. `label`\n * names it in messages, e.g. `Function \"rate\"`.\n */\nexport function assertHostSpec(spec: unknown, label: string): void {\n if (!isRecord(spec)) throw new TypeError(`${label} must be declared with fn()`)\n for (const key of Object.keys(spec)) {\n if (key === 'context') {\n throw new TypeError(\n `${label}: \"context: true\" is now \"call: true\"; run receives { context, signal } first`,\n )\n }\n if (!HOST_SPEC_KEYS.has(key)) throw new TypeError(`${label} has an unknown option \"${key}\"`)\n }\n if (!Array.isArray(spec.params)) throw new TypeError(`${label} needs a params array`)\n spec.params.forEach((param: unknown, i: number) => {\n assertType(param, `Parameter ${i + 1} of ${label}`)\n })\n assertType(spec.returns, `The returns type of ${label}`)\n if (spec.required !== undefined) {\n if (typeof spec.required !== 'number')\n throw new TypeError(`\"required\" of ${label} must be a number`)\n if (!Number.isInteger(spec.required) || spec.required < 0 || spec.required > spec.params.length)\n throw new RangeError(\n `\"required\" of ${label} must be an integer from 0 to ${spec.params.length}`,\n )\n }\n if (spec.rest !== undefined) assertType(spec.rest, `The rest type of ${label}`)\n for (const flag of ['async', 'call'] as const) {\n if (spec[flag] !== undefined && typeof spec[flag] !== 'boolean')\n throw new TypeError(`\"${flag}\" of ${label} must be a boolean`)\n }\n if (spec.description !== undefined && typeof spec.description !== 'string')\n throw new TypeError(`\"description\" of ${label} must be a string`)\n if (spec.cost !== undefined) {\n if (typeof spec.cost !== 'number') throw new TypeError(`\"cost\" of ${label} must be a number`)\n if (!Number.isSafeInteger(spec.cost) || spec.cost < 0)\n throw new RangeError(`\"cost\" of ${label} must be a non-negative integer`)\n }\n if (typeof spec.run !== 'function') throw new TypeError(`${label} needs a run function`)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"define.mjs","names":[],"sources":["../../src/functions/define.ts"],"sourcesContent":["import { BLOCKED_NAMES } from '../syntax/lexer.js'\nimport type { Span } from '../errors.js'\nimport type { State } from '../runtime/state.js'\nimport {\n Duration,\n isMap,\n isTimestamp,\n isValidDuration,\n keyListCost,\n shown,\n} from '../runtime/values.js'\nimport { formatType, typeText, type FunctionType, type Type, type TypeVar } from '../types.js'\n\n/** A lambda as seen by a built-in: called with the item and its index. */\nexport type Lambda = (item: unknown, index: number) => unknown\n\n/** Call-site information handed to a built-in implementation. */\nexport interface CallSite {\n readonly state: State\n readonly span: Span\n}\n\n/**\n * What async evaluation resolves to: a value in a box. JavaScript adopts (runs\n * `then` on) any thenable an async function returns or awaits, and data from\n * the host is opaque, never awaited, so values cross an `await` boxed.\n */\nexport class Out {\n readonly v: unknown\n constructor(v: unknown) {\n this.v = v\n }\n}\n\nexport interface Overload {\n /** Parameter types. Function-typed parameters take lambdas. */\n readonly params: readonly Type[]\n /** How many leading parameters are required (default: all). */\n readonly required?: number\n /** Type of any further arguments (variadic). */\n readonly rest?: Type\n /** Result type; may reference type variables bound by the parameters. */\n readonly result: Type\n readonly run: (args: unknown[], site: CallSite) => unknown\n /**\n * Variant used when a lambda argument is asynchronous. Its lambdas resolve\n * to an {@link Out}, and so does it.\n */\n readonly runAsync?: ((args: unknown[], site: CallSite) => Promise<Out>) | undefined\n /** Type variables that must bind to one orderable kind (number, string, timestamp, duration). */\n readonly ordered?: readonly string[]\n /**\n * Static validation of literal arguments (undefined where an argument is\n * not a literal). Returns an error message, so mistakes in constant\n * patterns are reported when the expression is checked.\n */\n readonly literals?: ((values: readonly unknown[]) => string | undefined) | undefined\n}\n\nexport interface FunctionDef {\n readonly name: string\n readonly description: string\n readonly overloads: readonly Overload[]\n /** Host functions: returns a promise and must be awaited. */\n readonly async?: boolean\n /** Host functions: receives a HostCall (context and signal) as its first argument. */\n readonly call?: boolean\n readonly host?: boolean\n /** Host functions: steps charged per call (default 32). */\n readonly cost?: number\n}\n\nexport const T: TypeVar = Object.freeze({ kind: 'var', name: 'T' })\nexport const U: TypeVar = Object.freeze({ kind: 'var', name: 'U' })\nexport const K: TypeVar = Object.freeze({ kind: 'var', name: 'K' })\n\nexport function fnType(params: readonly Type[], result: Type): FunctionType {\n return Object.freeze({ kind: 'function', params: Object.freeze([...params]), result })\n}\n\n/** An overload's signature as messages and hovers show it, e.g. `slice(string, number, number?): string`. */\nexport function signatureText(name: string, candidate: Overload): string {\n const required = candidate.required ?? candidate.params.length\n const params = candidate.params.map((param, i) => `${typeText(param)}${i >= required ? '?' : ''}`)\n if (candidate.rest !== undefined) params.push(`...${typeText(candidate.rest)}`)\n return `${name}(${params.join(', ')}): ${typeText(candidate.result)}`\n}\n\n/** Whether parameter `index` of any overload is function-typed (lambda position). */\nexport function isLambdaPosition(def: FunctionDef, index: number): boolean {\n return def.overloads.some((candidate) => candidate.params[index]?.kind === 'function')\n}\n\n/**\n * Whether `.` may stand for the lambda at `index`: its first parameter must be\n * the current item (the element of the list argument). In reduce it is the\n * accumulator, so `.` there would silently mean the wrong value.\n */\nexport function isItemLambdaPosition(def: FunctionDef, index: number): boolean {\n return def.overloads.some((candidate) => {\n const lambda = candidate.params[index]\n const items = candidate.params[0]\n if (lambda?.kind !== 'function' || items?.kind !== 'list') return false\n const first = lambda.params[0]\n const element = items.element\n return (\n first === element ||\n (first?.kind === 'var' && element.kind === 'var' && first.name === element.name)\n )\n })\n}\n\n/** Shallow runtime test used to pick an overload by argument kinds. */\nexport function matchesKind(value: unknown, type: Type): boolean {\n switch (type.kind) {\n case 'any':\n case 'var':\n return true\n case 'never':\n return false\n case 'null':\n return value === null || value === undefined\n case 'boolean':\n return typeof value === 'boolean'\n case 'number':\n return typeof value === 'number'\n case 'string':\n return typeof value === 'string'\n case 'literal':\n return value === type.value\n case 'list':\n return Array.isArray(value)\n case 'map':\n return isMap(value)\n case 'timestamp':\n return value instanceof Date\n case 'duration':\n return isValidDuration(value)\n case 'union':\n return type.types.some((member) => matchesKind(value, member))\n case 'opaque':\n return (\n value !== null &&\n value !== undefined &&\n (typeof value === 'function' ||\n typeof value === 'symbol' ||\n typeof value === 'bigint' ||\n typeof value === 'object')\n )\n case 'function':\n default:\n return typeof value === 'function'\n }\n}\n\n/** Deep runtime conformance, used to guard host function parameters. */\nexport function conforms(value: unknown, type: Type, state: State, depth = 0): boolean {\n if (depth > state.limits.maxValueDepth) return false\n switch (type.kind) {\n case 'list': {\n if (!Array.isArray(value)) return false\n if (type.element.kind === 'any') return true\n state.charge(value.length)\n // oxlint-disable-next-line typescript/prefer-for-of -- indexing never invokes a host array's own Symbol.iterator\n for (let i = 0; i < value.length; i++)\n if (!conforms(value[i], type.element, state, depth + 1)) return false\n return true\n }\n case 'map': {\n if (!isMap(value)) return false\n const fields = Object.entries(type.fields)\n state.charge(1 + fields.length)\n for (const [key, fieldType] of fields) {\n if (!conforms(Object.hasOwn(value, key) ? value[key] : null, fieldType, state, depth + 1))\n return false\n }\n if (type.rest !== undefined && type.rest.kind !== 'any') {\n const keys = Object.keys(value)\n state.charge(keyListCost(keys.length))\n for (const key of keys) {\n // A key holding undefined is absent (see holdsKey).\n const field = value[key]\n if (\n field !== undefined &&\n !Object.hasOwn(type.fields, key) &&\n !conforms(field, type.rest, state, depth + 1)\n )\n return false\n }\n }\n return true\n }\n case 'union':\n // Each member may be tried: a union of thousands of literals is real work.\n state.charge(type.types.length)\n return type.types.some((member) => conforms(value, member, state, depth))\n case 'timestamp':\n // An invalid Date is an opaque host value, not a timestamp.\n return isTimestamp(value)\n case 'duration':\n return isValidDuration(value)\n case 'any':\n case 'boolean':\n case 'function':\n case 'literal':\n case 'never':\n case 'null':\n case 'number':\n case 'opaque':\n case 'string':\n case 'var':\n default:\n return matchesKind(value, type)\n }\n}\n\nconst CLOCK_SAMPLE = 1024\n\nfunction describeValue(value: unknown): string {\n if (value === null) return 'null (missing)'\n if (Array.isArray(value)) return 'a list'\n if (value instanceof Date) return isTimestamp(value) ? 'a timestamp' : 'an invalid Date'\n if (value instanceof Duration && !isValidDuration(value)) return 'an invalid Duration'\n if (typeof value === 'object') return 'a map'\n if (typeof value === 'string') return `string ${shown(value)}`\n if (typeof value === 'number' || typeof value === 'boolean')\n return `${typeof value} ${String(value)}`\n return typeof value\n}\n\n/** Bounds context validation like evaluation: depth, work, and wall-clock time. */\nexport interface ValidationBudget {\n readonly maxDepth: number\n remaining: number\n readonly deadline: number\n readonly onExhausted: (reason: 'steps' | 'time' | 'depth') => never\n}\n\n/** Why `value` does not conform to `type` (naming the path), or undefined when it does. */\nexport function describeMismatch(\n value: unknown,\n type: Type,\n path: string,\n budget: ValidationBudget,\n depth = 0,\n): string | undefined {\n if (depth > budget.maxDepth) budget.onExhausted('depth')\n if (--budget.remaining < 0) budget.onExhausted('steps')\n if (\n budget.deadline !== 0 &&\n budget.remaining % CLOCK_SAMPLE === 0 &&\n performance.now() > budget.deadline\n ) {\n budget.onExhausted('time')\n }\n const actual = value === undefined ? null : value\n if (type.kind === 'list' && Array.isArray(actual)) {\n for (let i = 0; i < actual.length; i++) {\n const problem = describeMismatch(actual[i], type.element, `${path}[${i}]`, budget, depth + 1)\n if (problem !== undefined) return problem\n }\n return undefined\n }\n if (type.kind === 'map' && isMap(actual)) {\n for (const [key, fieldType] of Object.entries(type.fields)) {\n const field = Object.hasOwn(actual, key) ? actual[key] : null\n const problem = describeMismatch(field, fieldType, `${path}.${key}`, budget, depth + 1)\n if (problem !== undefined) return problem\n }\n if (type.rest !== undefined) {\n const keys = Object.keys(actual)\n // Listing a map's keys costs per key (see keyListCost), and more for a large one.\n budget.remaining -= keyListCost(keys.length)\n if (budget.remaining < 0) budget.onExhausted('steps')\n for (const key of keys) {\n // Keys the language can never read, or that hold undefined, are not part of the data.\n if (Object.hasOwn(type.fields, key) || BLOCKED_NAMES.has(key) || actual[key] === undefined)\n continue\n const problem = describeMismatch(\n actual[key],\n type.rest,\n `${path}.${key}`,\n budget,\n depth + 1,\n )\n if (problem !== undefined) return problem\n }\n }\n return undefined\n }\n if (type.kind === 'union') {\n if (\n type.types.some(\n (member) => describeMismatch(actual, member, path, budget, depth) === undefined,\n )\n ) {\n return undefined\n }\n } else if (type.kind === 'timestamp') {\n if (isTimestamp(actual)) return undefined\n } else if (type.kind === 'duration') {\n if (isValidDuration(actual)) return undefined\n } else if (type.kind === 'number') {\n // The language has no NaN or infinities, so a context holding one is not data it can read.\n if (typeof actual === 'number' && Number.isFinite(actual)) return undefined\n } else if (type.kind !== 'list' && type.kind !== 'map' && matchesKind(actual, type)) {\n return undefined\n }\n return `${path} should be ${formatType(type)}, got ${describeValue(actual)}`\n}\n\nexport function overload(\n params: readonly Type[],\n result: Type,\n run: Overload['run'],\n options: {\n required?: number\n rest?: Type\n runAsync?: Overload['runAsync']\n ordered?: readonly string[]\n literals?: Overload['literals']\n } = {},\n): Overload {\n return Object.freeze({ params: Object.freeze([...params]), result, run, ...options })\n}\n\nexport function define(\n name: string,\n description: string,\n overloads: readonly Overload[],\n): FunctionDef {\n return Object.freeze({ name, description, overloads: Object.freeze([...overloads]) })\n}\n\n// === validation of host-supplied declarations ===\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nfunction describe(value: unknown): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) return 'an array'\n return typeof value\n}\n\nconst TYPE_DEPTH_LIMIT = 64\n\n/**\n * Throws a TypeError unless `value` is a well-formed Type (as built by `t`).\n * Types come from configuration, so a malformed one is a programming error.\n */\nexport function assertType(value: unknown, path: string, depth = 0): asserts value is Type {\n if (depth > TYPE_DEPTH_LIMIT) throw new TypeError(`${path} nests deeper than ${TYPE_DEPTH_LIMIT}`)\n if (!isRecord(value) || typeof value.kind !== 'string') {\n throw new TypeError(`${path} must be a type built with t (got ${describe(value)})`)\n }\n switch (value.kind) {\n case 'any':\n case 'never':\n case 'null':\n case 'boolean':\n case 'number':\n case 'string':\n case 'timestamp':\n case 'duration':\n return\n case 'literal':\n if (!['string', 'number', 'boolean'].includes(typeof value.value)) {\n throw new TypeError(\n `${path} is a literal type whose value is not a string, number, or boolean`,\n )\n }\n if (typeof value.value === 'number' && !Number.isFinite(value.value))\n throw new TypeError(`${path} is a literal type whose number is not finite`)\n return\n case 'list':\n assertType(value.element, `${path}.element`, depth + 1)\n return\n case 'map':\n if (!isRecord(value.fields)) throw new TypeError(`${path}.fields must be an object`)\n for (const [key, field] of Object.entries(value.fields))\n assertType(field, `${path}.fields.${key}`, depth + 1)\n if (value.rest !== undefined) assertType(value.rest, `${path}.rest`, depth + 1)\n return\n case 'union':\n if (!Array.isArray(value.types)) throw new TypeError(`${path}.types must be an array`)\n // By index, so a hole (which forEach would skip) is refused like any non-type.\n for (let i = 0; i < value.types.length; i++)\n assertType(value.types[i], `${path}.types[${i}]`, depth + 1)\n return\n case 'opaque':\n if (typeof value.name !== 'string')\n throw new TypeError(`${path} is an opaque type without a name`)\n return\n case 'function':\n case 'var':\n default:\n throw new TypeError(`${path} has an unsupported type kind \"${value.kind}\"`)\n }\n}\n\nconst HOST_SPEC_KEYS = new Set([\n 'params',\n 'returns',\n 'required',\n 'rest',\n 'async',\n 'call',\n 'description',\n 'cost',\n 'run',\n])\n\n/**\n * Throws unless `spec` is a well-formed host function declaration. `label`\n * names it in messages, e.g. `Function \"rate\"`.\n */\nexport function assertHostSpec(spec: unknown, label: string): void {\n if (!isRecord(spec)) throw new TypeError(`${label} must be declared with fn()`)\n for (const key of Object.keys(spec)) {\n if (key === 'context') {\n throw new TypeError(\n `${label}: \"context: true\" is now \"call: true\"; run receives { context, signal } first`,\n )\n }\n if (!HOST_SPEC_KEYS.has(key)) throw new TypeError(`${label} has an unknown option \"${key}\"`)\n }\n if (!Array.isArray(spec.params)) throw new TypeError(`${label} needs a params array`)\n spec.params.forEach((param: unknown, i: number) => {\n assertType(param, `Parameter ${i + 1} of ${label}`)\n })\n assertType(spec.returns, `The returns type of ${label}`)\n if (spec.required !== undefined) {\n if (typeof spec.required !== 'number')\n throw new TypeError(`\"required\" of ${label} must be a number`)\n if (!Number.isInteger(spec.required) || spec.required < 0 || spec.required > spec.params.length)\n throw new RangeError(\n `\"required\" of ${label} must be an integer from 0 to ${spec.params.length}`,\n )\n }\n if (spec.rest !== undefined) assertType(spec.rest, `The rest type of ${label}`)\n for (const flag of ['async', 'call'] as const) {\n if (spec[flag] !== undefined && typeof spec[flag] !== 'boolean')\n throw new TypeError(`\"${flag}\" of ${label} must be a boolean`)\n }\n if (spec.description !== undefined && typeof spec.description !== 'string')\n throw new TypeError(`\"description\" of ${label} must be a string`)\n if (spec.cost !== undefined) {\n if (typeof spec.cost !== 'number') throw new TypeError(`\"cost\" of ${label} must be a number`)\n if (!Number.isSafeInteger(spec.cost) || spec.cost < 0)\n throw new RangeError(`\"cost\" of ${label} must be a non-negative integer`)\n }\n if (typeof spec.run !== 'function') throw new TypeError(`${label} needs a run function`)\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BonsaiCheckError, BonsaiError, BonsaiErrorJSON, BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, Diagnostic, DiagnosticCode, DiagnosticJSON, ErrorCode, LimitName, Span, isBonsaiError } from "./errors.mjs";
|
|
1
|
+
import { ArtifactProblem, BonsaiArtifactError, BonsaiCheckError, BonsaiError, BonsaiErrorJSON, BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, Diagnostic, DiagnosticCode, DiagnosticJSON, ErrorCode, LimitName, Span, isBonsaiError } from "./errors.mjs";
|
|
2
2
|
import { BinaryNode, BinaryOperator, CallNode, CallStyle, ConditionalNode, HasNode, IndexNode, ItNode, LambdaNode, LetNode, ListNode, LiteralNode, LocalNode, MapEntry, MapNode, MemberNode, Node, SpreadNode, TemplateNode, TryNode, UnaryNode, UnaryOperator, VariableNode, forEachChild, mapChildren } from "./syntax/ast.mjs";
|
|
3
3
|
import { ExplanationJSON, Iteration, IterationJSON, Trace, TraceJSON } from "./runtime/trace.mjs";
|
|
4
4
|
import { Duration } from "./runtime/values.mjs";
|
|
@@ -6,6 +6,7 @@ import { AnyType, BooleanType, DurationType, FunctionType, Infer, InferVariables
|
|
|
6
6
|
import { PartialData, PartialOptions, PartialResult, ResidualResult } from "./partial.mjs";
|
|
7
7
|
import { AbortSignalLike, CheckResult, CompileOptions, Environment, EnvironmentOptions, EvaluateOptions, ExplainOptions, Explanation, FnSpec, FunctionInfo, HostCall, HostFunction, Library, Limits, Program, fn, withContext } from "./environment.mjs";
|
|
8
8
|
import { bonsai } from "./bonsai.mjs";
|
|
9
|
+
import { Artifact, Plan, toArtifact } from "./artifact.mjs";
|
|
9
10
|
import { ParseOptions, parse } from "./parse.mjs";
|
|
10
11
|
import { PrintOptions, print } from "./syntax/printer.mjs";
|
|
11
|
-
export { type AbortSignalLike, type AnyType, type BinaryNode, type BinaryOperator, BonsaiCheckError, BonsaiError, type BonsaiErrorJSON, type BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, type BooleanType, type CallNode, type CallStyle, type CheckResult, type CompileOptions, type ConditionalNode, type Diagnostic, type DiagnosticCode, type DiagnosticJSON, Duration, type DurationType, type Environment, type EnvironmentOptions, type ErrorCode, type EvaluateOptions, type ExplainOptions, type Explanation, type ExplanationJSON, type FnSpec, type FunctionInfo, type FunctionType, type HasNode, type HostCall, type HostFunction, type IndexNode, type Infer, type InferVariables, type ItNode, type Iteration, type IterationJSON, type LambdaNode, type LetNode, type Library, type LimitName, type Limits, type ListNode, type ListType, type LiteralNode, type LiteralType, type LocalNode, type MapEntry, type MapNode, type MapType, type MemberNode, type NeverType, type Node, type NullType, type NumberType, type OpaqueType, type ParseOptions, type PartialData, type PartialOptions, type PartialResult, type PrintOptions, type Program, type ResidualResult, type Span, type SpreadNode, type StringType, type TemplateNode, type TimestampType, type Trace, type TraceJSON, type TryNode, type Type, type TypeVar, type UnaryNode, type UnaryOperator, type UnionType, type VariableNode, bonsai, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, withContext };
|
|
12
|
+
export { type AbortSignalLike, type AnyType, type Artifact, type ArtifactProblem, type BinaryNode, type BinaryOperator, BonsaiArtifactError, BonsaiCheckError, BonsaiError, type BonsaiErrorJSON, type BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, type BooleanType, type CallNode, type CallStyle, type CheckResult, type CompileOptions, type ConditionalNode, type Diagnostic, type DiagnosticCode, type DiagnosticJSON, Duration, type DurationType, type Environment, type EnvironmentOptions, type ErrorCode, type EvaluateOptions, type ExplainOptions, type Explanation, type ExplanationJSON, type FnSpec, type FunctionInfo, type FunctionType, type HasNode, type HostCall, type HostFunction, type IndexNode, type Infer, type InferVariables, type ItNode, type Iteration, type IterationJSON, type LambdaNode, type LetNode, type Library, type LimitName, type Limits, type ListNode, type ListType, type LiteralNode, type LiteralType, type LocalNode, type MapEntry, type MapNode, type MapType, type MemberNode, type NeverType, type Node, type NullType, type NumberType, type OpaqueType, type ParseOptions, type PartialData, type PartialOptions, type PartialResult, type Plan, type PrintOptions, type Program, type ResidualResult, type Span, type SpreadNode, type StringType, type TemplateNode, type TimestampType, type Trace, type TraceJSON, type TryNode, type Type, type TypeVar, type UnaryNode, type UnaryOperator, type UnionType, type VariableNode, bonsai, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, toArtifact, withContext };
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, isBonsaiError } from "./errors.mjs";
|
|
1
|
+
import { BonsaiArtifactError, BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, isBonsaiError } from "./errors.mjs";
|
|
2
2
|
import { Duration } from "./runtime/values.mjs";
|
|
3
3
|
import { formatType, isAssignable, t } from "./types.mjs";
|
|
4
4
|
import { forEachChild, mapChildren } from "./syntax/ast.mjs";
|
|
5
5
|
import { fn, withContext } from "./environment.mjs";
|
|
6
6
|
import { print } from "./syntax/printer.mjs";
|
|
7
7
|
import { bonsai } from "./bonsai.mjs";
|
|
8
|
+
import { toArtifact } from "./artifact.mjs";
|
|
8
9
|
import { parse } from "./parse.mjs";
|
|
9
|
-
export { BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, Duration, bonsai, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, withContext };
|
|
10
|
+
export { BonsaiArtifactError, BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, BonsaiTranslationError, Duration, bonsai, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, toArtifact, withContext };
|
package/dist/lite/index.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { BonsaiCheckError, BonsaiError, BonsaiErrorJSON, BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, Diagnostic, DiagnosticCode, DiagnosticJSON, ErrorCode, LimitName, Span, isBonsaiError } from "../errors.mjs";
|
|
1
|
+
import { ArtifactProblem, BonsaiArtifactError, BonsaiCheckError, BonsaiError, BonsaiErrorJSON, BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, Diagnostic, DiagnosticCode, DiagnosticJSON, ErrorCode, LimitName, Span, isBonsaiError } from "../errors.mjs";
|
|
2
2
|
import { BinaryNode, BinaryOperator, CallNode, CallStyle, ConditionalNode, HasNode, IndexNode, ItNode, LambdaNode, LetNode, ListNode, LiteralNode, LocalNode, MapEntry, MapNode, MemberNode, Node, SpreadNode, TemplateNode, TryNode, UnaryNode, UnaryOperator, VariableNode, forEachChild, mapChildren } from "../syntax/ast.mjs";
|
|
3
3
|
import { Duration } from "../runtime/values.mjs";
|
|
4
4
|
import { AnyType, BooleanType, DurationType, FunctionType, Infer, InferVariables, ListType, LiteralType, MapType, NeverType, NullType, NumberType, OpaqueType, StringType, TimestampType, Type, TypeVar, UnionType, formatType, isAssignable, t } from "../types.mjs";
|
|
5
5
|
import { AbortSignalLike, CompileOptions, ContextFor, EnvironmentOptions, EvaluateOptions, FnSpec, FunctionInfo, HostCall, HostFunction, Library, Limits, LiteCheckResult, LiteEnvironment, LiteProgram, NoVariables, fn, withContext } from "../environment.mjs";
|
|
6
|
+
import { Artifact, Plan, toArtifact } from "../artifact.mjs";
|
|
6
7
|
import { ParseOptions, parse } from "../parse.mjs";
|
|
7
8
|
import { PrintOptions, print } from "../syntax/printer.mjs";
|
|
8
9
|
//#region src/lite/index.d.ts
|
|
@@ -20,4 +21,4 @@ export declare function bonsai<const V extends Readonly<Record<string, Type>> =
|
|
|
20
21
|
readonly strict?: S;
|
|
21
22
|
}): LiteEnvironment<ContextFor<V, L, S>>;
|
|
22
23
|
//#endregion
|
|
23
|
-
export { type AbortSignalLike, type AnyType, type BinaryNode, type BinaryOperator, BonsaiCheckError, BonsaiError, type BonsaiErrorJSON, type BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, type BooleanType, type CallNode, type CallStyle, type CompileOptions, type ConditionalNode, type Diagnostic, type DiagnosticCode, type DiagnosticJSON, Duration, type DurationType, type EnvironmentOptions, type ErrorCode, type EvaluateOptions, type FnSpec, type FunctionInfo, type FunctionType, type HasNode, type HostCall, type HostFunction, type IndexNode, type Infer, type InferVariables, type ItNode, type LambdaNode, type LetNode, type Library, type LimitName, type Limits, type ListNode, type ListType, type LiteCheckResult, type LiteEnvironment, type LiteProgram, type LiteralNode, type LiteralType, type LocalNode, type MapEntry, type MapNode, type MapType, type MemberNode, type NeverType, type Node, type NullType, type NumberType, type OpaqueType, type ParseOptions, type PrintOptions, type Span, type SpreadNode, type StringType, type TemplateNode, type TimestampType, type TryNode, type Type, type TypeVar, type UnaryNode, type UnaryOperator, type UnionType, type VariableNode, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, withContext };
|
|
24
|
+
export { type AbortSignalLike, type AnyType, type Artifact, type ArtifactProblem, type BinaryNode, type BinaryOperator, BonsaiArtifactError, BonsaiCheckError, BonsaiError, type BonsaiErrorJSON, type BonsaiErrorName, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, type BooleanType, type CallNode, type CallStyle, type CompileOptions, type ConditionalNode, type Diagnostic, type DiagnosticCode, type DiagnosticJSON, Duration, type DurationType, type EnvironmentOptions, type ErrorCode, type EvaluateOptions, type FnSpec, type FunctionInfo, type FunctionType, type HasNode, type HostCall, type HostFunction, type IndexNode, type Infer, type InferVariables, type ItNode, type LambdaNode, type LetNode, type Library, type LimitName, type Limits, type ListNode, type ListType, type LiteCheckResult, type LiteEnvironment, type LiteProgram, type LiteralNode, type LiteralType, type LocalNode, type MapEntry, type MapNode, type MapType, type MemberNode, type NeverType, type Node, type NullType, type NumberType, type OpaqueType, type ParseOptions, type Plan, type PrintOptions, type Span, type SpreadNode, type StringType, type TemplateNode, type TimestampType, type TryNode, type Type, type TypeVar, type UnaryNode, type UnaryOperator, type UnionType, type VariableNode, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, toArtifact, withContext };
|
package/dist/lite/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, isBonsaiError } from "../errors.mjs";
|
|
1
|
+
import { BonsaiArtifactError, BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, isBonsaiError } from "../errors.mjs";
|
|
2
2
|
import { Duration } from "../runtime/values.mjs";
|
|
3
3
|
import { formatType, isAssignable, t } from "../types.mjs";
|
|
4
4
|
import { forEachChild, mapChildren } from "../syntax/ast.mjs";
|
|
5
5
|
import { environmentWith, fn, withContext } from "../environment.mjs";
|
|
6
6
|
import { print } from "../syntax/printer.mjs";
|
|
7
|
+
import { toArtifact } from "../artifact.mjs";
|
|
7
8
|
import { parse } from "../parse.mjs";
|
|
8
9
|
//#region src/lite/index.ts
|
|
9
10
|
/**
|
|
@@ -26,6 +27,6 @@ function bonsai(options = {}) {
|
|
|
26
27
|
return environmentWith(void 0, options);
|
|
27
28
|
}
|
|
28
29
|
//#endregion
|
|
29
|
-
export { BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, Duration, bonsai, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, withContext };
|
|
30
|
+
export { BonsaiArtifactError, BonsaiCheckError, BonsaiError, BonsaiLimitError, BonsaiRuntimeError, BonsaiSyntaxError, Duration, bonsai, fn, forEachChild, formatType, isAssignable, isBonsaiError, mapChildren, parse, print, t, toArtifact, withContext };
|
|
30
31
|
|
|
31
32
|
//# sourceMappingURL=index.mjs.map
|
package/dist/lite/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/lite/index.ts"],"sourcesContent":["/**\n * `bonsai-js/lite`: the `bonsai-js` API without explaining and partial\n * evaluation, for bundles that only check and evaluate expressions.\n * Environments and programs from this entry point have no `explain`,\n * `explainSync`, or `partial`; everything else behaves as in `bonsai-js`.\n */\nimport {\n environmentWith,\n type ContextFor,\n type EnvironmentOptions,\n type Library,\n type LiteEnvironment,\n type NoVariables,\n} from '../environment.js'\nimport type { Type } from '../types.js'\n\n/**\n * Creates an environment without explaining and partial evaluation: the\n * variables, functions, and limits expressions are checked and evaluated against.\n *\n * ```ts\n * const env = bonsai({ variables: { user: t.object({ age: t.number() }) } })\n * const adult = env.compile('user.age >= 18', { expect: t.boolean() })\n * adult.evaluateSync({ user: { age: 30 } }) // true\n * ```\n */\nexport function bonsai<\n const V extends Readonly<Record<string, Type>> = NoVariables,\n const L extends readonly Library[] = [],\n const S extends boolean | undefined = undefined,\n>(\n options: EnvironmentOptions<V, L> & { readonly strict?: S } = {},\n): LiteEnvironment<ContextFor<V, L, S>> {\n return environmentWith<ContextFor<V, L, S>>(undefined, options)\n}\n\nexport { fn, withContext } from '../environment.js'\nexport type {\n AbortSignalLike,\n CompileOptions,\n EnvironmentOptions,\n EvaluateOptions,\n FnSpec,\n FunctionInfo,\n HostCall,\n HostFunction,\n Library,\n Limits,\n LiteCheckResult,\n LiteEnvironment,\n LiteProgram,\n} from '../environment.js'\nexport { t, formatType, isAssignable } from '../types.js'\nexport type {\n AnyType,\n BooleanType,\n DurationType,\n FunctionType,\n Infer,\n InferVariables,\n ListType,\n LiteralType,\n MapType,\n NeverType,\n NullType,\n NumberType,\n OpaqueType,\n StringType,\n TimestampType,\n Type,\n TypeVar,\n UnionType,\n} from '../types.js'\nexport { Duration } from '../runtime/values.js'\nexport {\n BonsaiError,\n BonsaiSyntaxError,\n BonsaiCheckError,\n BonsaiLimitError,\n BonsaiRuntimeError,\n isBonsaiError,\n} from '../errors.js'\nexport type {\n BonsaiErrorJSON,\n BonsaiErrorName,\n Diagnostic,\n DiagnosticJSON,\n DiagnosticCode,\n ErrorCode,\n LimitName,\n Span,\n} from '../errors.js'\nexport { forEachChild, mapChildren } from '../syntax/ast.js'\nexport type {\n BinaryNode,\n BinaryOperator,\n CallNode,\n CallStyle,\n ConditionalNode,\n HasNode,\n IndexNode,\n ItNode,\n LambdaNode,\n LetNode,\n ListNode,\n LiteralNode,\n LocalNode,\n MapEntry,\n MapNode,\n MemberNode,\n Node,\n SpreadNode,\n TemplateNode,\n TryNode,\n UnaryNode,\n UnaryOperator,\n VariableNode,\n} from '../syntax/ast.js'\nexport { parse, type ParseOptions } from '../parse.js'\nexport { print, type PrintOptions } from '../syntax/printer.js'\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/lite/index.ts"],"sourcesContent":["/**\n * `bonsai-js/lite`: the `bonsai-js` API without explaining and partial\n * evaluation, for bundles that only check and evaluate expressions.\n * Environments and programs from this entry point have no `explain`,\n * `explainSync`, or `partial`; everything else behaves as in `bonsai-js`.\n */\nimport {\n environmentWith,\n type ContextFor,\n type EnvironmentOptions,\n type Library,\n type LiteEnvironment,\n type NoVariables,\n} from '../environment.js'\nimport type { Type } from '../types.js'\n\n/**\n * Creates an environment without explaining and partial evaluation: the\n * variables, functions, and limits expressions are checked and evaluated against.\n *\n * ```ts\n * const env = bonsai({ variables: { user: t.object({ age: t.number() }) } })\n * const adult = env.compile('user.age >= 18', { expect: t.boolean() })\n * adult.evaluateSync({ user: { age: 30 } }) // true\n * ```\n */\nexport function bonsai<\n const V extends Readonly<Record<string, Type>> = NoVariables,\n const L extends readonly Library[] = [],\n const S extends boolean | undefined = undefined,\n>(\n options: EnvironmentOptions<V, L> & { readonly strict?: S } = {},\n): LiteEnvironment<ContextFor<V, L, S>> {\n return environmentWith<ContextFor<V, L, S>>(undefined, options)\n}\n\nexport { fn, withContext } from '../environment.js'\nexport type {\n AbortSignalLike,\n CompileOptions,\n EnvironmentOptions,\n EvaluateOptions,\n FnSpec,\n FunctionInfo,\n HostCall,\n HostFunction,\n Library,\n Limits,\n LiteCheckResult,\n LiteEnvironment,\n LiteProgram,\n} from '../environment.js'\nexport { t, formatType, isAssignable } from '../types.js'\nexport type {\n AnyType,\n BooleanType,\n DurationType,\n FunctionType,\n Infer,\n InferVariables,\n ListType,\n LiteralType,\n MapType,\n NeverType,\n NullType,\n NumberType,\n OpaqueType,\n StringType,\n TimestampType,\n Type,\n TypeVar,\n UnionType,\n} from '../types.js'\nexport { Duration } from '../runtime/values.js'\nexport {\n BonsaiError,\n BonsaiSyntaxError,\n BonsaiCheckError,\n BonsaiLimitError,\n BonsaiRuntimeError,\n BonsaiArtifactError,\n isBonsaiError,\n} from '../errors.js'\nexport type {\n ArtifactProblem,\n BonsaiErrorJSON,\n BonsaiErrorName,\n Diagnostic,\n DiagnosticJSON,\n DiagnosticCode,\n ErrorCode,\n LimitName,\n Span,\n} from '../errors.js'\nexport { forEachChild, mapChildren } from '../syntax/ast.js'\nexport type {\n BinaryNode,\n BinaryOperator,\n CallNode,\n CallStyle,\n ConditionalNode,\n HasNode,\n IndexNode,\n ItNode,\n LambdaNode,\n LetNode,\n ListNode,\n LiteralNode,\n LocalNode,\n MapEntry,\n MapNode,\n MemberNode,\n Node,\n SpreadNode,\n TemplateNode,\n TryNode,\n UnaryNode,\n UnaryOperator,\n VariableNode,\n} from '../syntax/ast.js'\nexport { toArtifact, type Artifact, type Plan } from '../artifact.js'\nexport { parse, type ParseOptions } from '../parse.js'\nexport { print, type PrintOptions } from '../syntax/printer.js'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,OAKd,UAA8D,CAAC,GACzB;CACtC,OAAO,gBAAqC,KAAA,GAAW,OAAO;AAChE"}
|