@rcrsr/rill 0.16.0 → 0.17.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.
Files changed (57) hide show
  1. package/README.md +37 -21
  2. package/dist/ext/crypto/index.d.ts +3 -3
  3. package/dist/ext/crypto/index.js +61 -58
  4. package/dist/ext/exec/index.d.ts +3 -3
  5. package/dist/ext/exec/index.js +14 -8
  6. package/dist/ext/fetch/index.d.ts +3 -3
  7. package/dist/ext/fetch/index.js +16 -11
  8. package/dist/ext/fs/index.d.ts +3 -3
  9. package/dist/ext/fs/index.js +242 -239
  10. package/dist/ext/kv/index.d.ts +3 -3
  11. package/dist/ext/kv/index.js +197 -195
  12. package/dist/ext/kv/store.js +2 -1
  13. package/dist/ext-parse-bridge.d.ts +10 -0
  14. package/dist/ext-parse-bridge.js +10 -0
  15. package/dist/generated/introspection-data.d.ts +1 -1
  16. package/dist/generated/introspection-data.js +385 -296
  17. package/dist/generated/version-data.d.ts +1 -1
  18. package/dist/generated/version-data.js +2 -2
  19. package/dist/index.d.ts +15 -4
  20. package/dist/index.js +14 -5
  21. package/dist/parser/parser-types.js +12 -0
  22. package/dist/parser/parser-use.js +7 -1
  23. package/dist/runtime/core/callable.d.ts +20 -8
  24. package/dist/runtime/core/callable.js +63 -23
  25. package/dist/runtime/core/context.d.ts +0 -11
  26. package/dist/runtime/core/context.js +76 -75
  27. package/dist/runtime/core/eval/index.d.ts +2 -2
  28. package/dist/runtime/core/eval/index.js +11 -0
  29. package/dist/runtime/core/eval/mixins/closures.js +15 -15
  30. package/dist/runtime/core/eval/mixins/conversion.js +51 -110
  31. package/dist/runtime/core/eval/mixins/core.js +2 -2
  32. package/dist/runtime/core/eval/mixins/expressions.js +35 -27
  33. package/dist/runtime/core/eval/mixins/literals.js +3 -3
  34. package/dist/runtime/core/eval/mixins/types.js +44 -54
  35. package/dist/runtime/core/eval/mixins/variables.js +10 -8
  36. package/dist/runtime/core/field-descriptor.d.ts +3 -3
  37. package/dist/runtime/core/field-descriptor.js +2 -1
  38. package/dist/runtime/core/introspection.js +6 -6
  39. package/dist/runtime/core/markers.d.ts +12 -0
  40. package/dist/runtime/core/markers.js +7 -0
  41. package/dist/runtime/core/type-registrations.d.ts +136 -0
  42. package/dist/runtime/core/type-registrations.js +749 -0
  43. package/dist/runtime/core/type-structures.d.ts +128 -0
  44. package/dist/runtime/core/type-structures.js +12 -0
  45. package/dist/runtime/core/types.d.ts +15 -3
  46. package/dist/runtime/core/values.d.ts +62 -153
  47. package/dist/runtime/core/values.js +308 -524
  48. package/dist/runtime/ext/builtins.js +83 -64
  49. package/dist/runtime/ext/extensions.d.ts +30 -124
  50. package/dist/runtime/ext/extensions.js +0 -93
  51. package/dist/runtime/ext/test-context.d.ts +28 -0
  52. package/dist/runtime/ext/test-context.js +154 -0
  53. package/dist/runtime/index.d.ts +22 -8
  54. package/dist/runtime/index.js +18 -4
  55. package/dist/signature-parser.d.ts +2 -2
  56. package/dist/signature-parser.js +14 -14
  57. package/package.json +1 -1
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Test Context Factory
3
+ *
4
+ * Creates a pre-wired RuntimeContext from extension value maps.
5
+ * Designed for testing and lightweight embedding without rill-config.
6
+ */
7
+ import { parseSource } from '../../ext-parse-bridge.js';
8
+ import { createRuntimeContext } from '../core/context.js';
9
+ import { extResolver } from '../core/resolvers.js';
10
+ import { isCallable } from '../core/callable.js';
11
+ import { formatStructure } from '../core/values.js';
12
+ // ============================================================
13
+ // ERROR CLASS
14
+ // ============================================================
15
+ /**
16
+ * Error thrown when extension binding generation fails.
17
+ * Mirrors the ExtensionBindingError in rill-config for core-only usage.
18
+ */
19
+ export class ExtensionBindingError extends Error {
20
+ code = 'EXTENSION_BINDING';
21
+ constructor(message) {
22
+ super(message);
23
+ this.name = 'ExtensionBindingError';
24
+ }
25
+ }
26
+ // ============================================================
27
+ // BINDING GENERATOR
28
+ // ============================================================
29
+ /**
30
+ * Format a RillParam as a rill source parameter declaration.
31
+ * Produces `name: type` syntax matching the parser's closure annotation grammar.
32
+ */
33
+ function formatParam(param) {
34
+ const typeName = param.type !== undefined ? formatStructure(param.type) : 'any';
35
+ return `${param.name}: ${typeName}`;
36
+ }
37
+ /**
38
+ * Check if a RillValue is a plain dict (not a callable, tuple, vector, etc.).
39
+ */
40
+ function isPlainDict(value) {
41
+ return (typeof value === 'object' &&
42
+ value !== null &&
43
+ !Array.isArray(value) &&
44
+ !isCallable(value) &&
45
+ !('__rill_tuple' in value) &&
46
+ !('__rill_vector' in value) &&
47
+ !('__rill_ordered' in value) &&
48
+ !('__rill_type' in value) &&
49
+ !('__rill_field_descriptor' in value));
50
+ }
51
+ /**
52
+ * Generate rill source for a nested value tree.
53
+ * Callable leaves produce `use<ext:path>:|params| :returnType`.
54
+ * Dict nodes recurse. All other values produce `use<ext:path>`.
55
+ */
56
+ function buildNestedSource(value, path, indent) {
57
+ if (isCallable(value)) {
58
+ const c = value;
59
+ const paramStr = c.params.map(formatParam).join(', ');
60
+ const returnSuffix = ` :${formatStructure(c.returnType.structure)}`;
61
+ return `use<ext:${path}>:|${paramStr}|${returnSuffix}`;
62
+ }
63
+ if (isPlainDict(value)) {
64
+ const entries = Object.entries(value);
65
+ if (entries.length === 0)
66
+ return '[:]';
67
+ const childIndent = indent + ' ';
68
+ const parts = entries.map(([key, child]) => {
69
+ const childPath = path.length > 0 ? `${path}.${key}` : key;
70
+ const childSource = buildNestedSource(child, childPath, childIndent);
71
+ return `${childIndent}${key}: ${childSource}`;
72
+ });
73
+ return `[\n${parts.join(',\n')}\n${indent}]`;
74
+ }
75
+ // Scalar, list, tuple, vector: resolve directly via ext resolver
76
+ return `use<ext:${path}>`;
77
+ }
78
+ /**
79
+ * Generate rill source bindings from an extension value map.
80
+ * Returns a rill dict literal suitable for use as module:ext source.
81
+ *
82
+ * @throws {ExtensionBindingError} when binding generation fails
83
+ */
84
+ function buildExtensionBindings(extensions) {
85
+ try {
86
+ const entries = Object.entries(extensions);
87
+ if (entries.length === 0)
88
+ return '[:]';
89
+ const parts = entries.map(([name, value]) => {
90
+ const source = buildNestedSource(value, name, '');
91
+ return ` ${name}: ${source}`;
92
+ });
93
+ return `[\n${parts.join(',\n')}\n]`;
94
+ }
95
+ catch (err) {
96
+ const reason = err instanceof Error ? err.message : String(err);
97
+ throw new ExtensionBindingError(`Failed to generate extension bindings: ${reason}`);
98
+ }
99
+ }
100
+ // ============================================================
101
+ // MODULE RESOLVER FOR EXT BINDINGS
102
+ // ============================================================
103
+ /**
104
+ * Create a module resolver that serves generated extension binding source.
105
+ * Handles only the `ext` resource; rejects all other module IDs.
106
+ */
107
+ function createExtModuleResolver(bindingSource) {
108
+ return (resource) => {
109
+ if (resource === 'ext') {
110
+ return { kind: 'source', text: bindingSource, sourceId: 'module:ext' };
111
+ }
112
+ throw new Error(`Unknown module '${resource}'`);
113
+ };
114
+ }
115
+ // ============================================================
116
+ // PUBLIC API
117
+ // ============================================================
118
+ /**
119
+ * Create a RuntimeContext pre-wired with extension values.
120
+ * Builds extension bindings, registers ext and module resolvers,
121
+ * and returns a context ready for execute().
122
+ *
123
+ * @throws {TypeError} when an extension value is undefined (EC-9)
124
+ * @throws {ExtensionBindingError} when binding generation fails (EC-10)
125
+ */
126
+ export function createTestContext(extensions) {
127
+ // EC-9: Validate no undefined extension values
128
+ for (const [name, entry] of Object.entries(extensions)) {
129
+ if (entry.value === undefined) {
130
+ throw new TypeError(`Extension '${name}' has undefined value`);
131
+ }
132
+ }
133
+ // Build ext resolver config: maps extension names to their RillValues
134
+ const extConfig = {};
135
+ for (const [name, entry] of Object.entries(extensions)) {
136
+ extConfig[name] = entry.value;
137
+ }
138
+ // Generate rill source bindings (EC-10: propagates ExtensionBindingError)
139
+ const bindingSource = buildExtensionBindings(extConfig);
140
+ // Create module resolver for ext bindings
141
+ const extModuleResolver = createExtModuleResolver(bindingSource);
142
+ return createRuntimeContext({
143
+ resolvers: {
144
+ ext: extResolver,
145
+ module: extModuleResolver,
146
+ },
147
+ configurations: {
148
+ resolvers: {
149
+ ext: extConfig,
150
+ },
151
+ },
152
+ parseSource,
153
+ });
154
+ }
@@ -18,19 +18,33 @@
18
18
  */
19
19
  export type { CaptureEvent, ErrorEvent, ExecutionResult, ExecutionStepper, HostCallEvent, FunctionReturnEvent, ObservabilityCallbacks, ResolverResult, RuntimeCallbacks, RuntimeContext, RuntimeOptions, SchemeResolver, StepEndEvent, StepResult, StepStartEvent, } from './core/types.js';
20
20
  export type { ApplicationCallable, CallableFn, RillCallable, RillFunction, RillParam, RuntimeCallable, ScriptCallable, } from './core/callable.js';
21
- export { callable, isApplicationCallable, isCallable, isDict, isRuntimeCallable, isScriptCallable, } from './core/callable.js';
22
- export type { NativeArray, NativePlainObject, NativeResult, NativeValue, RillFieldDef, RillIterator, RillTuple, RillType, RillTypeValue, RillValue, RillVector, } from './core/values.js';
23
- /** @deprecated Use RillType instead. Will be removed in the next major version. */
24
- export type { RillStructuralType } from './core/values.js';
25
- export { anyTypeValue, commonType, createTuple, createVector, formatStructuralType, inferElementType, inferStructuralType, inferType, isRillIterator, isTuple, isTypeValue, isVector, isReservedMethod, paramToFieldDef, rillTypeToTypeValue, RESERVED_DICT_METHODS, structuralTypeEquals, structuralTypeMatches, toNative, } from './core/values.js';
21
+ export { callable, isApplicationCallable, isCallable, isDict, isRuntimeCallable, isScriptCallable, toCallable, } from './core/callable.js';
22
+ export type { NativeArray, NativePlainObject, NativeResult, NativeValue, RillFieldDef, RillIterator, RillTuple, RillTypeValue, RillValue, RillVector, TypeStructure, } from './core/values.js';
23
+ /** @deprecated Use TypeStructure instead. Will be removed in the next major version. */
24
+ export type { RillType } from './core/values.js';
25
+ export type { TypeDefinition, TypeProtocol, } from './core/type-registrations.js';
26
+ export { anyTypeValue, commonType, createTuple, createVector, formatStructure, inferElementType, inferStructure, inferType, isIterator, isTuple, isTypeValue, isVector, isReservedMethod, paramToFieldDef, structureToTypeValue, RESERVED_DICT_METHODS, structureEquals, structureMatches, toNative, } from './core/values.js';
27
+ /** @deprecated Use formatStructure instead. */
28
+ export { formatStructuralType } from './core/values.js';
29
+ /** @deprecated Use inferStructure instead. */
30
+ export { inferStructuralType } from './core/values.js';
31
+ /** @deprecated Use isIterator instead. */
32
+ export { isRillIterator } from './core/values.js';
33
+ /** @deprecated Use structureToTypeValue instead. */
34
+ export { rillTypeToTypeValue } from './core/values.js';
35
+ /** @deprecated Use structureEquals instead. */
36
+ export { structuralTypeEquals } from './core/values.js';
37
+ /** @deprecated Use structureMatches instead. */
38
+ export { structuralTypeMatches } from './core/values.js';
26
39
  export { buildFieldDescriptor } from './core/field-descriptor.js';
27
40
  export { BreakSignal, ReturnSignal } from './core/signals.js';
28
41
  export type { ExtensionEvent } from './core/types.js';
29
- export type { ConfigFieldDescriptor, ExtensionConfigSchema, ExtensionFactory, ExtensionManifest, ExtensionResult, FsExtensionContract, HoistedExtension, KvExtensionContract, LlmExtensionContract, VectorExtensionContract, } from './ext/extensions.js';
42
+ export type { ConfigFieldDescriptor, ExtensionConfigSchema, ExtensionFactory, ExtensionFactoryResult, ExtensionManifest, FsExtensionContract, KvExtensionContract, } from './ext/extensions.js';
30
43
  export type { SchemaEntry } from '../ext/kv/index.js';
31
- export { prefixFunctions, emitExtensionEvent, hoistExtension, } from './ext/extensions.js';
44
+ export { emitExtensionEvent } from './ext/extensions.js';
32
45
  export { contextResolver, extResolver, moduleResolver, } from './core/resolvers.js';
33
- export { buildTypeMethodDicts, createRuntimeContext } from './core/context.js';
46
+ export { createRuntimeContext } from './core/context.js';
47
+ export { createTestContext, ExtensionBindingError, } from './ext/test-context.js';
34
48
  export type { CallFrame } from '../types.js';
35
49
  export { getCallStack, pushCallFrame, popCallFrame } from './core/context.js';
36
50
  export { createStepper, execute } from './core/execute.js';
@@ -16,14 +16,27 @@
16
16
  * - ext/: Self-contained extensions
17
17
  * - builtins.ts: Built-in functions and methods
18
18
  */
19
- export { callable, isApplicationCallable, isCallable, isDict, isRuntimeCallable, isScriptCallable, } from './core/callable.js';
20
- export { anyTypeValue, commonType, createTuple, createVector, formatStructuralType, inferElementType, inferStructuralType, inferType, isRillIterator, isTuple, isTypeValue, isVector, isReservedMethod, paramToFieldDef, rillTypeToTypeValue, RESERVED_DICT_METHODS, structuralTypeEquals, structuralTypeMatches, toNative, } from './core/values.js';
19
+ export { callable, isApplicationCallable, isCallable, isDict, isRuntimeCallable, isScriptCallable, toCallable, } from './core/callable.js';
20
+ export { anyTypeValue, commonType, createTuple, createVector, formatStructure, inferElementType, inferStructure, inferType, isIterator, isTuple, isTypeValue, isVector, isReservedMethod, paramToFieldDef, structureToTypeValue, RESERVED_DICT_METHODS, structureEquals, structureMatches, toNative, } from './core/values.js';
21
+ // Deprecated aliases — old names kept for one release
22
+ /** @deprecated Use formatStructure instead. */
23
+ export { formatStructuralType } from './core/values.js';
24
+ /** @deprecated Use inferStructure instead. */
25
+ export { inferStructuralType } from './core/values.js';
26
+ /** @deprecated Use isIterator instead. */
27
+ export { isRillIterator } from './core/values.js';
28
+ /** @deprecated Use structureToTypeValue instead. */
29
+ export { rillTypeToTypeValue } from './core/values.js';
30
+ /** @deprecated Use structureEquals instead. */
31
+ export { structuralTypeEquals } from './core/values.js';
32
+ /** @deprecated Use structureMatches instead. */
33
+ export { structuralTypeMatches } from './core/values.js';
21
34
  export { buildFieldDescriptor } from './core/field-descriptor.js';
22
35
  // ============================================================
23
36
  // CONTROL FLOW SIGNALS
24
37
  // ============================================================
25
38
  export { BreakSignal, ReturnSignal } from './core/signals.js';
26
- export { prefixFunctions, emitExtensionEvent, hoistExtension, } from './ext/extensions.js';
39
+ export { emitExtensionEvent } from './ext/extensions.js';
27
40
  // ============================================================
28
41
  // BUILT-IN RESOLVERS
29
42
  // ============================================================
@@ -31,7 +44,8 @@ export { contextResolver, extResolver, moduleResolver, } from './core/resolvers.
31
44
  // ============================================================
32
45
  // CONTEXT FACTORY
33
46
  // ============================================================
34
- export { buildTypeMethodDicts, createRuntimeContext } from './core/context.js';
47
+ export { createRuntimeContext } from './core/context.js';
48
+ export { createTestContext, ExtensionBindingError, } from './ext/test-context.js';
35
49
  export { getCallStack, pushCallFrame, popCallFrame } from './core/context.js';
36
50
  // ============================================================
37
51
  // SCRIPT EXECUTION
@@ -12,13 +12,13 @@
12
12
  * which is NOT in parser/* or lexer/* — boundary preserved.
13
13
  */
14
14
  import type { RillParam } from './runtime/core/callable.js';
15
- import type { RillType } from './runtime/core/values.js';
15
+ import type { TypeStructure } from './runtime/core/values.js';
16
16
  /**
17
17
  * Result of parsing a signature string at registration time.
18
18
  */
19
19
  export interface ParsedSignature {
20
20
  readonly params: RillParam[];
21
- readonly returnType: RillType | undefined;
21
+ readonly returnType: TypeStructure | undefined;
22
22
  readonly description: string | undefined;
23
23
  }
24
24
  /**
@@ -15,38 +15,38 @@ import { tokenize } from './lexer/index.js';
15
15
  import { ParseError, TOKEN_TYPES } from './types.js';
16
16
  import { createParserState, advance, check, current, expect, skipNewlines, isAtEnd, parseTypeRef, } from './parser/index.js';
17
17
  // ============================================================
18
- // TypeRef → RillType static conversion
18
+ // TypeRef → TypeStructure static conversion
19
19
  // ============================================================
20
20
  /**
21
- * Convert a static TypeRef to a RillType.
21
+ * Convert a static TypeRef to a TypeStructure.
22
22
  *
23
23
  * Only handles static refs (type names and unions). Dynamic refs ($var)
24
24
  * are not valid in registration-time signatures — they throw Error.
25
25
  *
26
26
  * @internal
27
27
  */
28
- function staticTypeRefToRillType(typeRef, functionName) {
28
+ function staticTypeRefToTypeStructure(typeRef, functionName) {
29
29
  if (typeRef.kind === 'dynamic') {
30
30
  throw new Error(`Invalid signature for function '${functionName}': dynamic type references ($variable) are not allowed in signatures`);
31
31
  }
32
32
  if (typeRef.kind === 'union') {
33
33
  return {
34
- type: 'union',
35
- members: typeRef.members.map((m) => staticTypeRefToRillType(m, functionName)),
34
+ kind: 'union',
35
+ members: typeRef.members.map((m) => staticTypeRefToTypeStructure(m, functionName)),
36
36
  };
37
37
  }
38
38
  // static kind
39
39
  const { typeName, args } = typeRef;
40
40
  if (!args || args.length === 0) {
41
- return { type: typeName };
41
+ return { kind: typeName };
42
42
  }
43
43
  // Parameterized types
44
44
  if (typeName === 'list') {
45
45
  if (args.length === 1 &&
46
46
  args[0] !== undefined &&
47
47
  args[0].name === undefined) {
48
- const element = staticTypeRefToRillType(args[0].value, functionName);
49
- return { type: 'list', element };
48
+ const element = staticTypeRefToTypeStructure(args[0].value, functionName);
49
+ return { kind: 'list', element };
50
50
  }
51
51
  throw new Error(`Invalid signature for function '${functionName}': list requires exactly one positional type argument`);
52
52
  }
@@ -57,17 +57,17 @@ function staticTypeRefToRillType(typeRef, functionName) {
57
57
  throw new Error(`Invalid signature for function '${functionName}': dict type arguments must be named (e.g. dict(key: string))`);
58
58
  }
59
59
  fields[arg.name] = {
60
- type: staticTypeRefToRillType(arg.value, functionName),
60
+ type: staticTypeRefToTypeStructure(arg.value, functionName),
61
61
  };
62
62
  }
63
- return { type: 'dict', fields };
63
+ return { kind: 'dict', fields };
64
64
  }
65
65
  if (typeName === 'tuple') {
66
66
  const elements = args.map((arg) => ({
67
67
  ...(arg.name !== undefined ? { name: arg.name } : {}),
68
- type: staticTypeRefToRillType(arg.value, functionName),
68
+ type: staticTypeRefToTypeStructure(arg.value, functionName),
69
69
  }));
70
- return { type: 'tuple', elements };
70
+ return { kind: 'tuple', elements };
71
71
  }
72
72
  throw new Error(`Invalid signature for function '${functionName}': type '${typeName}' does not accept type arguments`);
73
73
  }
@@ -205,7 +205,7 @@ function parseSignatureBody(state, functionName) {
205
205
  advance(state); // consume :
206
206
  skipNewlines(state);
207
207
  const typeRef = parseTypeRef(state);
208
- returnType = staticTypeRefToRillType(typeRef, functionName);
208
+ returnType = staticTypeRefToTypeStructure(typeRef, functionName);
209
209
  }
210
210
  // Step 5: Verify no trailing tokens
211
211
  if (!isAtEnd(state)) {
@@ -244,7 +244,7 @@ function parseSignatureParam(state, functionName) {
244
244
  advance(state); // consume :
245
245
  skipNewlines(state);
246
246
  const typeRef = parseTypeRef(state, { allowTrailingPipe: true });
247
- type = staticTypeRefToRillType(typeRef, functionName);
247
+ type = staticTypeRefToTypeStructure(typeRef, functionName);
248
248
  }
249
249
  // Optional default value = literal
250
250
  let defaultValue = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rcrsr/rill",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Scripting designed for machine-generated code",
5
5
  "license": "MIT",
6
6
  "author": "Andre Bremer",