@opencode/codemode 0.0.0-dev-19530 → 2.0.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 (62) hide show
  1. package/dist/data.d.ts +5 -6
  2. package/dist/data.js +44 -47
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +1 -0
  5. package/dist/interpreter/errors.d.ts +3 -5
  6. package/dist/interpreter/errors.js +22 -51
  7. package/dist/interpreter/execute.js +3 -5
  8. package/dist/interpreter/globals.js +47 -69
  9. package/dist/interpreter/host.d.ts +41 -0
  10. package/dist/interpreter/host.js +44 -0
  11. package/dist/interpreter/methods.d.ts +4 -0
  12. package/dist/interpreter/methods.js +837 -0
  13. package/dist/interpreter/model.d.ts +36 -13
  14. package/dist/interpreter/model.js +45 -15
  15. package/dist/interpreter/objects.d.ts +13 -106
  16. package/dist/interpreter/objects.js +65 -192
  17. package/dist/interpreter/promises.d.ts +13 -12
  18. package/dist/interpreter/promises.js +54 -59
  19. package/dist/interpreter/references.d.ts +0 -1
  20. package/dist/interpreter/references.js +33 -20
  21. package/dist/interpreter/runner.d.ts +11 -15
  22. package/dist/interpreter/runner.js +21 -21
  23. package/dist/interpreter/runtime.d.ts +3 -3
  24. package/dist/interpreter/runtime.js +327 -165
  25. package/dist/interpreter/scope.js +6 -6
  26. package/dist/stdlib/array.d.ts +2 -4
  27. package/dist/stdlib/array.js +32 -424
  28. package/dist/stdlib/collections.d.ts +7 -3
  29. package/dist/stdlib/collections.js +119 -291
  30. package/dist/stdlib/console.d.ts +2 -3
  31. package/dist/stdlib/console.js +30 -35
  32. package/dist/stdlib/date.d.ts +7 -1
  33. package/dist/stdlib/date.js +188 -93
  34. package/dist/stdlib/json.d.ts +2 -2
  35. package/dist/stdlib/json.js +27 -27
  36. package/dist/stdlib/math.d.ts +2 -2
  37. package/dist/stdlib/math.js +76 -96
  38. package/dist/stdlib/number.d.ts +4 -3
  39. package/dist/stdlib/number.js +60 -95
  40. package/dist/stdlib/object.d.ts +4 -4
  41. package/dist/stdlib/object.js +54 -128
  42. package/dist/stdlib/regexp.d.ts +8 -6
  43. package/dist/stdlib/regexp.js +68 -76
  44. package/dist/stdlib/string.d.ts +2 -2
  45. package/dist/stdlib/string.js +50 -213
  46. package/dist/stdlib/url.d.ts +13 -5
  47. package/dist/stdlib/url.js +102 -202
  48. package/dist/stdlib/value.d.ts +9 -5
  49. package/dist/stdlib/value.js +38 -16
  50. package/dist/stdlib/web.d.ts +4 -4
  51. package/dist/stdlib/web.js +10 -12
  52. package/dist/tool-runtime.d.ts +1 -2
  53. package/dist/tool-runtime.js +2 -2
  54. package/dist/values.d.ts +37 -0
  55. package/dist/values.js +56 -0
  56. package/package.json +1 -1
  57. package/dist/interpreter/generators.d.ts +0 -4
  58. package/dist/interpreter/generators.js +0 -25
  59. package/dist/interpreter/intrinsics.d.ts +0 -13
  60. package/dist/interpreter/intrinsics.js +0 -82
  61. package/dist/interpreter/native.d.ts +0 -19
  62. package/dist/interpreter/native.js +0 -40
@@ -1,6 +1,8 @@
1
1
  import type { Node } from "acorn";
2
- import type { ErrorType } from "./intrinsics.js";
2
+ import type { Effect } from "effect";
3
3
  import type { DiagnosticKind } from "../codemode.js";
4
+ import type { ProgramObject } from "./objects.js";
5
+ import type { Values } from "../values.js";
4
6
  /** Any parsed node; the interpreter narrows on `type` and reads `loc` for diagnostics. */
5
7
  export type AstNode = Node;
6
8
  export type Binding = {
@@ -20,10 +22,39 @@ export type StatementResult = {
20
22
  kind: "continue";
21
23
  label?: string;
22
24
  };
25
+ export type MemberReference = {
26
+ target: ProgramObject | Values.RegExp | Values.URL;
27
+ key: PropertyKey;
28
+ };
23
29
  export type GeneratorRequestKind = "next" | "return" | "throw";
30
+ export declare class CodeModeGenerator {
31
+ readonly asynchronous: boolean;
32
+ readonly request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>;
33
+ constructor(asynchronous: boolean, request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>);
34
+ }
35
+ export declare class GeneratorMethodReference {
36
+ readonly generator: CodeModeGenerator;
37
+ readonly kind: GeneratorRequestKind | "iterator";
38
+ constructor(generator: CodeModeGenerator, kind: GeneratorRequestKind | "iterator");
39
+ }
40
+ export declare class IntrinsicReference {
41
+ readonly receiver: unknown;
42
+ readonly name: string;
43
+ constructor(receiver: unknown, name: string);
44
+ }
45
+ export declare class ComputedValue {
46
+ readonly value: unknown;
47
+ constructor(value: unknown);
48
+ }
24
49
  export declare const AsyncIteratorSymbol: unique symbol;
25
50
  export declare const IteratorSymbol: unique symbol;
26
51
  export declare const IteratorSymbols: readonly [typeof AsyncIteratorSymbol, typeof IteratorSymbol];
52
+ export type PromiseInstanceMethodName = "then" | "catch" | "finally";
53
+ export declare class PromiseInstanceMethodReference {
54
+ readonly promise: Values.Promise;
55
+ readonly name: PromiseInstanceMethodName;
56
+ constructor(promise: Values.Promise, name: PromiseInstanceMethodName);
57
+ }
27
58
  export declare class ProgramThrow {
28
59
  readonly value: unknown;
29
60
  constructor(value: unknown);
@@ -36,19 +67,11 @@ export declare const OptionalShortCircuit: unique symbol;
36
67
  export declare class InterpreterRuntimeError extends Error {
37
68
  readonly kind: DiagnosticKind;
38
69
  readonly suggestions?: ReadonlyArray<string> | undefined;
39
- /** The JS error class a program sees when it catches this failure. */
40
- readonly type: ErrorType;
41
70
  readonly node?: AstNode;
42
- constructor(message: string, node?: AstNode, kind?: DiagnosticKind, suggestions?: ReadonlyArray<string> | undefined,
43
- /** The JS error class a program sees when it catches this failure. */
44
- type?: ErrorType);
45
- }
46
- /** Attaches a source location to a failure raised where none was known, such as inside a property accessor. */
47
- export declare const locate: (error: unknown, node: AstNode) => unknown;
48
- export declare const rangeError: (message: string, node?: AstNode) => InterpreterRuntimeError;
49
- export declare const referenceError: (message: string, node?: AstNode) => InterpreterRuntimeError;
50
- export declare const syntaxError: (message: string, node?: AstNode) => InterpreterRuntimeError;
51
- export declare const uriError: (message: string, node?: AstNode) => InterpreterRuntimeError;
71
+ errorName: string;
72
+ constructor(message: string, node?: AstNode, kind?: DiagnosticKind, suggestions?: ReadonlyArray<string> | undefined);
73
+ as(errorName: string): this;
74
+ }
52
75
  export declare const supportedSyntaxMessage = "This is a restricted JavaScript-like language. Supported: plain and async functions, data literals, destructuring, standard control flow, await and Promise, and built-ins such as Array, Object, Math, JSON, Date, RegExp, Map, Set, and URL. Unsupported: classes, this, getters/setters, tagged templates, BigInt, and custom Symbols. Use plain functions and data objects instead.";
53
76
  export declare const unsupportedSyntax: (kind: string, node: AstNode) => InterpreterRuntimeError;
54
77
  export declare const isRecord: (value: unknown) => value is Record<string, unknown>;
@@ -1,6 +1,44 @@
1
+ export class CodeModeGenerator {
2
+ asynchronous;
3
+ request;
4
+ constructor(asynchronous, request) {
5
+ this.asynchronous = asynchronous;
6
+ this.request = request;
7
+ }
8
+ }
9
+ export class GeneratorMethodReference {
10
+ generator;
11
+ kind;
12
+ constructor(generator, kind) {
13
+ this.generator = generator;
14
+ this.kind = kind;
15
+ }
16
+ }
17
+ export class IntrinsicReference {
18
+ receiver;
19
+ name;
20
+ constructor(receiver, name) {
21
+ this.receiver = receiver;
22
+ this.name = name;
23
+ }
24
+ }
25
+ export class ComputedValue {
26
+ value;
27
+ constructor(value) {
28
+ this.value = value;
29
+ }
30
+ }
1
31
  export const AsyncIteratorSymbol = Symbol("codemode.async-iterator");
2
32
  export const IteratorSymbol = Symbol("codemode.iterator");
3
33
  export const IteratorSymbols = [AsyncIteratorSymbol, IteratorSymbol];
34
+ export class PromiseInstanceMethodReference {
35
+ promise;
36
+ name;
37
+ constructor(promise, name) {
38
+ this.promise = promise;
39
+ this.name = name;
40
+ }
41
+ }
4
42
  export class ProgramThrow {
5
43
  value;
6
44
  constructor(value) {
@@ -17,32 +55,24 @@ export const OptionalShortCircuit = Symbol("codemode.optional-short-circuit");
17
55
  export class InterpreterRuntimeError extends Error {
18
56
  kind;
19
57
  suggestions;
20
- type;
21
58
  node;
22
- constructor(message, node, kind = "ExecutionFailure", suggestions,
23
- /** The JS error class a program sees when it catches this failure. */
24
- type = "TypeError") {
59
+ errorName = "Error";
60
+ constructor(message, node, kind = "ExecutionFailure", suggestions) {
25
61
  super(message);
26
62
  this.kind = kind;
27
63
  this.suggestions = suggestions;
28
- this.type = type;
29
64
  this.name = "InterpreterRuntimeError";
30
65
  if (node)
31
66
  this.node = node;
32
67
  }
68
+ as(errorName) {
69
+ this.errorName = errorName;
70
+ return this;
71
+ }
33
72
  }
34
- /** Attaches a source location to a failure raised where none was known, such as inside a property accessor. */
35
- export const locate = (error, node) => error instanceof InterpreterRuntimeError && error.node === undefined
36
- ? new InterpreterRuntimeError(error.message, node, error.kind, error.suggestions, error.type)
37
- : error;
38
- const failure = (type) => (message, node) => new InterpreterRuntimeError(message, node, "ExecutionFailure", undefined, type);
39
- export const rangeError = failure("RangeError");
40
- export const referenceError = failure("ReferenceError");
41
- export const syntaxError = failure("SyntaxError");
42
- export const uriError = failure("URIError");
43
73
  // Orient the agent rather than enumerate JavaScript; interpreter-support.md is the full matrix.
44
74
  export const supportedSyntaxMessage = "This is a restricted JavaScript-like language. Supported: plain and async functions, data literals, destructuring, standard control flow, await and Promise, and built-ins such as Array, Object, Math, JSON, Date, RegExp, Map, Set, and URL. Unsupported: classes, this, getters/setters, tagged templates, BigInt, and custom Symbols. Use plain functions and data objects instead.";
45
- export const unsupportedSyntax = (kind, node) => new InterpreterRuntimeError(`Syntax '${kind}' is not supported. ${supportedSyntaxMessage}`, node, "UnsupportedSyntax", [supportedSyntaxMessage], "SyntaxError");
75
+ export const unsupportedSyntax = (kind, node) => new InterpreterRuntimeError(`Syntax '${kind}' is not supported. ${supportedSyntaxMessage}`, node, "UnsupportedSyntax", [supportedSyntaxMessage]);
46
76
  export const isRecord = (value) => typeof value === "object" && value !== null;
47
77
  export const sourceLocation = (node) => ({
48
78
  line: Math.max(1, (node.loc?.start.line ?? 2) - 1),
@@ -1,130 +1,37 @@
1
1
  import type { BlockStatement, Expression, Pattern } from "acorn";
2
- import type { Effect, Fiber } from "effect";
3
- import { type AstNode, type Binding, type GeneratorRequestKind } from "./model.js";
4
- /** Property attributes, as in a JS property descriptor. */
5
- export type Attributes = {
6
- readonly writable: boolean;
7
- readonly enumerable: boolean;
8
- readonly configurable: boolean;
9
- };
10
- export type Getter = (receiver: unknown) => unknown;
11
- export type Setter = (receiver: unknown, value: unknown) => void;
12
- /** One own property: a data slot or a native accessor pair. */
13
- export type Slot = {
14
- value: unknown;
15
- writable: boolean;
16
- enumerable: boolean;
17
- configurable: boolean;
18
- } | {
19
- get: Getter | undefined;
20
- set: Setter | undefined;
21
- enumerable: boolean;
22
- configurable: boolean;
23
- };
24
- /** Ordinary assignment: writable, enumerable, configurable. */
25
- export declare const data: Attributes;
26
- /** Built-in methods and `constructor`: writable and configurable but hidden from enumeration. */
27
- export declare const hidden: Attributes;
28
- /** Function `name` and `length`: read-only but deletable. */
29
- export declare const readonly: Attributes;
30
- /** Constants such as `Math.PI` and a constructor's `prototype`. */
31
- export declare const frozen: Attributes;
2
+ import { type Binding } from "./model.js";
32
3
  /** An object owned by the program: own properties plus a prototype link. */
33
4
  export declare class ProgramObject {
34
5
  proto: ProgramObject | null;
35
- readonly props: Map<string | symbol, Slot>;
36
- constructor(proto: ProgramObject | null);
6
+ readonly props: Map<PropertyKey, unknown>;
7
+ constructor(proto?: ProgramObject | null);
37
8
  }
38
9
  export declare class ProgramArray extends ProgramObject {
39
10
  readonly items: Array<unknown>;
40
- constructor(proto: ProgramObject, items?: Array<unknown>);
11
+ constructor(items?: Array<unknown>);
41
12
  }
42
- /** An object with the [[ErrorData]] slot: what `Error.prototype.toString` and the host boundary recognize as an error. */
43
13
  export declare class ProgramError extends ProgramObject {
14
+ readonly errorName: string;
15
+ constructor(errorName: string);
44
16
  }
45
- export declare abstract class Callable extends ProgramObject {
46
- constructor(proto: ProgramObject, name: string, length: number);
47
- }
48
- export declare class ProgramFunction extends Callable {
17
+ export declare class ProgramFunction extends ProgramObject {
18
+ readonly name: string;
49
19
  readonly parameters: ReadonlyArray<Pattern>;
50
20
  readonly body: BlockStatement | Expression;
51
21
  readonly capturedScopes: ReadonlyArray<Map<string, Binding>>;
52
22
  readonly async: boolean;
53
23
  readonly generator: boolean;
54
- constructor(proto: ProgramObject, name: string, parameters: ReadonlyArray<Pattern>, body: BlockStatement | Expression, capturedScopes: ReadonlyArray<Map<string, Binding>>, async: boolean, generator: boolean);
55
- }
56
- export type NativeCall<R> = (thisValue: unknown, args: Array<unknown>, node: AstNode) => Effect.Effect<unknown, unknown, R>;
57
- export type NativeConstruct<R> = (args: Array<unknown>, newTarget: Callable, node: AstNode) => Effect.Effect<unknown, unknown, R>;
58
- export type NativeOptions<R> = {
59
- readonly name: string;
60
- readonly length?: number;
61
- readonly call: NativeCall<R>;
62
- /** `new name(...)`; without it the function is not a constructor. */
63
- readonly construct?: NativeConstruct<R>;
64
- /** Whether callback sites (array methods, replacers, promise reactions) admit this function. Defaults to true. */
65
- readonly callback?: boolean;
66
- };
67
- export declare class NativeFunction<R = never> extends Callable {
68
- readonly call: NativeCall<R>;
69
- readonly construct: NativeConstruct<R> | undefined;
70
- readonly callback: boolean;
71
- constructor(proto: ProgramObject, options: NativeOptions<R>);
72
- }
73
- export declare class ProgramPromise extends ProgramObject {
74
- readonly fiber: Fiber.Fiber<unknown, unknown>;
75
- constructor(proto: ProgramObject, fiber: Fiber.Fiber<unknown, unknown>);
76
- }
77
- export declare class ProgramGenerator extends ProgramObject {
78
- readonly asynchronous: boolean;
79
- readonly request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>;
80
- constructor(proto: ProgramObject, asynchronous: boolean, request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>);
81
- }
82
- export declare class ProgramDate extends ProgramObject {
83
- time: number;
84
- constructor(proto: ProgramObject, time: number);
85
- }
86
- export declare class ProgramRegExp extends ProgramObject {
87
- readonly regex: RegExp;
88
- constructor(proto: ProgramObject, pattern: string, flags: string);
89
- }
90
- export declare class ProgramMap extends ProgramObject {
91
- readonly map: Map<unknown, unknown>;
92
- }
93
- export declare class ProgramSet extends ProgramObject {
94
- readonly set: Set<unknown>;
95
- }
96
- export declare class ProgramURLSearchParams extends ProgramObject {
97
- readonly params: URLSearchParams;
98
- constructor(proto: ProgramObject, params: URLSearchParams);
99
- }
100
- export declare class ProgramURL extends ProgramObject {
101
- readonly url: URL;
102
- readonly searchParams: ProgramURLSearchParams;
103
- constructor(proto: ProgramObject, searchParamsProto: ProgramObject, url: URL);
24
+ readonly length: number;
25
+ constructor(name: string, parameters: ReadonlyArray<Pattern>, body: BlockStatement | Expression, capturedScopes: ReadonlyArray<Map<string, Binding>>, async: boolean, generator: boolean);
104
26
  }
105
- /** Built-in objects that wrap a host value; data-like, but never plain data. */
106
- export declare const isWrapper: (value: unknown) => value is ProgramDate | ProgramRegExp | ProgramMap | ProgramSet | ProgramURL | ProgramURLSearchParams;
107
27
  export declare const parseArrayIndex: (key: string | number) => number | undefined;
108
- /** The own property under `key`, including an array's live indexes and `length`. */
109
- export declare const own: (target: ProgramObject, key: PropertyKey) => Slot | undefined;
110
28
  export declare const hasOwn: (target: ProgramObject, key: PropertyKey) => boolean;
111
29
  export declare const getOwn: (target: ProgramObject, key: PropertyKey) => unknown;
112
- /** [[Get]]: walks the prototype chain; accessors see `receiver`, which is the primitive for wrapper prototypes. */
113
- export declare const get: (target: ProgramObject, key: PropertyKey, receiver?: unknown) => unknown;
30
+ export declare const get: (target: ProgramObject, key: PropertyKey) => unknown;
114
31
  export declare const has: (target: ProgramObject, key: PropertyKey) => boolean;
115
- export declare const hasPrototype: (value: unknown, proto: ProgramObject) => boolean;
116
- /** [[Set]]: an inherited setter or read-only property decides before an own data property is created. */
117
32
  export declare const set: (target: ProgramObject, key: PropertyKey, value: unknown) => boolean;
118
- /** [[DefineOwnProperty]] for a data property, ignoring the chain. */
119
- export declare const define: (target: ProgramObject, key: PropertyKey, value: unknown, attrs?: Attributes) => void;
120
- export declare const defineAccessor: (target: ProgramObject, key: PropertyKey, get: Getter, set?: Setter) => void;
121
33
  export declare const remove: (target: ProgramObject, key: PropertyKey) => boolean;
122
34
  export declare const ownKeys: (target: ProgramObject) => Array<string | symbol>;
123
- /** Own enumerable keys, including the iterator symbols; what spread and `Object.assign` copy. */
124
- export declare const enumerableKeys: (target: ProgramObject) => Array<string | symbol>;
125
- /** Own enumerable string keys: `Object.keys`. */
126
- export declare const keys: (target: ProgramObject) => Array<string>;
127
- /** Own enumerable string entries: `Object.entries` and serialization. */
128
- export declare const entries: (target: ProgramObject) => Array<[string, unknown]>;
129
- export declare const record: (proto: ProgramObject, fields: Record<string, unknown>) => ProgramObject;
35
+ export declare const ownEntries: (target: ProgramObject) => Array<[string, unknown]>;
36
+ export declare const record: (entries: Record<string, unknown>) => ProgramObject;
130
37
  export declare const assign: (target: ProgramObject, source: ProgramObject, skip?: ReadonlySet<PropertyKey>) => void;
@@ -1,124 +1,46 @@
1
1
  import { AsyncIteratorSymbol, IteratorSymbol } from "./model.js";
2
- /** Ordinary assignment: writable, enumerable, configurable. */
3
- export const data = { writable: true, enumerable: true, configurable: true };
4
- /** Built-in methods and `constructor`: writable and configurable but hidden from enumeration. */
5
- export const hidden = { writable: true, enumerable: false, configurable: true };
6
- /** Function `name` and `length`: read-only but deletable. */
7
- export const readonly = { writable: false, enumerable: false, configurable: true };
8
- /** Constants such as `Math.PI` and a constructor's `prototype`. */
9
- export const frozen = { writable: false, enumerable: false, configurable: false };
10
2
  /** An object owned by the program: own properties plus a prototype link. */
11
3
  export class ProgramObject {
12
4
  proto;
13
5
  props = new Map();
14
- constructor(proto) {
6
+ constructor(proto = null) {
15
7
  this.proto = proto;
16
8
  }
17
9
  }
18
10
  export class ProgramArray extends ProgramObject {
19
11
  items;
20
- constructor(proto, items = []) {
21
- super(proto);
12
+ constructor(items = []) {
13
+ super();
22
14
  this.items = items;
23
15
  }
24
16
  }
25
- /** An object with the [[ErrorData]] slot: what `Error.prototype.toString` and the host boundary recognize as an error. */
26
17
  export class ProgramError extends ProgramObject {
27
- }
28
- export class Callable extends ProgramObject {
29
- constructor(proto, name, length) {
30
- super(proto);
31
- define(this, "length", length, readonly);
32
- define(this, "name", name, readonly);
18
+ errorName;
19
+ constructor(errorName) {
20
+ super();
21
+ this.errorName = errorName;
33
22
  }
34
23
  }
35
- export class ProgramFunction extends Callable {
24
+ export class ProgramFunction extends ProgramObject {
25
+ name;
36
26
  parameters;
37
27
  body;
38
28
  capturedScopes;
39
29
  async;
40
30
  generator;
41
- constructor(proto, name, parameters, body, capturedScopes, async, generator) {
42
- const optional = parameters.findIndex((p) => p.type === "AssignmentPattern" || p.type === "RestElement");
43
- super(proto, name, optional === -1 ? parameters.length : optional);
31
+ length;
32
+ constructor(name, parameters, body, capturedScopes, async, generator) {
33
+ super();
34
+ this.name = name;
44
35
  this.parameters = parameters;
45
36
  this.body = body;
46
37
  this.capturedScopes = capturedScopes;
47
38
  this.async = async;
48
39
  this.generator = generator;
40
+ const optional = parameters.findIndex((p) => p.type === "AssignmentPattern" || p.type === "RestElement");
41
+ this.length = optional === -1 ? parameters.length : optional;
49
42
  }
50
43
  }
51
- export class NativeFunction extends Callable {
52
- call;
53
- construct;
54
- callback;
55
- constructor(proto, options) {
56
- super(proto, options.name, options.length ?? 0);
57
- this.call = options.call;
58
- this.construct = options.construct;
59
- this.callback = options.callback ?? true;
60
- }
61
- }
62
- export class ProgramPromise extends ProgramObject {
63
- fiber;
64
- constructor(proto, fiber) {
65
- super(proto);
66
- this.fiber = fiber;
67
- }
68
- }
69
- export class ProgramGenerator extends ProgramObject {
70
- asynchronous;
71
- request;
72
- constructor(proto, asynchronous, request) {
73
- super(proto);
74
- this.asynchronous = asynchronous;
75
- this.request = request;
76
- }
77
- }
78
- export class ProgramDate extends ProgramObject {
79
- time;
80
- constructor(proto, time) {
81
- super(proto);
82
- this.time = time;
83
- }
84
- }
85
- export class ProgramRegExp extends ProgramObject {
86
- regex;
87
- constructor(proto, pattern, flags) {
88
- super(proto);
89
- this.regex = new RegExp(pattern, flags);
90
- define(this, "lastIndex", 0, { writable: true, enumerable: false, configurable: false });
91
- }
92
- }
93
- export class ProgramMap extends ProgramObject {
94
- map = new Map();
95
- }
96
- export class ProgramSet extends ProgramObject {
97
- set = new Set();
98
- }
99
- export class ProgramURLSearchParams extends ProgramObject {
100
- params;
101
- constructor(proto, params) {
102
- super(proto);
103
- this.params = params;
104
- }
105
- }
106
- export class ProgramURL extends ProgramObject {
107
- url;
108
- searchParams;
109
- constructor(proto, searchParamsProto, url) {
110
- super(proto);
111
- this.url = url;
112
- this.searchParams = new ProgramURLSearchParams(searchParamsProto, url.searchParams);
113
- }
114
- }
115
- /** Built-in objects that wrap a host value; data-like, but never plain data. */
116
- export const isWrapper = (value) => value instanceof ProgramDate ||
117
- value instanceof ProgramRegExp ||
118
- value instanceof ProgramMap ||
119
- value instanceof ProgramSet ||
120
- value instanceof ProgramURL ||
121
- value instanceof ProgramURLSearchParams;
122
44
  const MAX_ARRAY_LENGTH = 4_294_967_295;
123
45
  export const parseArrayIndex = (key) => {
124
46
  const property = String(key);
@@ -129,119 +51,72 @@ export const parseArrayIndex = (key) => {
129
51
  };
130
52
  const canonical = (key) => (typeof key === "symbol" ? key : String(key));
131
53
  const index = (target, key) => target instanceof ProgramArray && typeof key === "string" ? parseArrayIndex(key) : undefined;
132
- /** The own property under `key`, including an array's live indexes and `length`. */
133
- export const own = (target, key) => {
54
+ // Non-enumerable built-in properties: array length, function name and length.
55
+ const builtin = (target, name) => (name === "length" && target instanceof ProgramArray) ||
56
+ ((name === "name" || name === "length") && target instanceof ProgramFunction);
57
+ export const hasOwn = (target, key) => {
134
58
  const name = canonical(key);
135
- if (target instanceof ProgramArray) {
136
- const at = index(target, name);
137
- if (at !== undefined) {
138
- return at in target.items ? { value: target.items[at], ...data } : undefined;
139
- }
140
- if (name === "length")
141
- return { value: target.items.length, writable: true, enumerable: false, configurable: false };
142
- }
143
- return target.props.get(name);
59
+ const at = index(target, name);
60
+ if (at !== undefined)
61
+ return at in target.items;
62
+ return builtin(target, name) || target.props.has(name);
144
63
  };
145
- const read = (slot, receiver) => "value" in slot ? slot.value : slot.get === undefined ? undefined : slot.get(receiver);
146
- export const hasOwn = (target, key) => own(target, key) !== undefined;
147
64
  export const getOwn = (target, key) => {
148
- const slot = own(target, key);
149
- return slot === undefined ? undefined : read(slot, target);
65
+ const name = canonical(key);
66
+ const at = index(target, name);
67
+ if (at !== undefined)
68
+ return target.items[at];
69
+ if (target instanceof ProgramArray && name === "length")
70
+ return target.items.length;
71
+ if (target instanceof ProgramFunction && name === "name")
72
+ return target.name;
73
+ if (target instanceof ProgramFunction && name === "length")
74
+ return target.length;
75
+ return target.props.get(name);
150
76
  };
151
- /** [[Get]]: walks the prototype chain; accessors see `receiver`, which is the primitive for wrapper prototypes. */
152
- export const get = (target, key, receiver = target) => {
77
+ export const get = (target, key) => {
153
78
  for (let current = target; current !== null; current = current.proto) {
154
- const slot = own(current, key);
155
- if (slot !== undefined)
156
- return read(slot, receiver);
79
+ if (hasOwn(current, key))
80
+ return getOwn(current, key);
157
81
  }
158
82
  return undefined;
159
83
  };
160
84
  export const has = (target, key) => {
161
85
  for (let current = target; current !== null; current = current.proto) {
162
- if (own(current, key) !== undefined)
86
+ if (hasOwn(current, key))
163
87
  return true;
164
88
  }
165
89
  return false;
166
90
  };
167
- export const hasPrototype = (value, proto) => {
168
- for (let current = value instanceof ProgramObject ? value.proto : null; current !== null; current = current.proto) {
169
- if (current === proto)
170
- return true;
171
- }
172
- return false;
173
- };
174
- const writeArray = (target, name, value) => {
91
+ export const set = (target, key, value) => {
92
+ const name = canonical(key);
175
93
  const at = index(target, name);
176
94
  if (at !== undefined) {
95
+ ;
177
96
  target.items[at] = value;
178
97
  return true;
179
98
  }
180
- if (name !== "length")
181
- return undefined;
182
- const length = typeof value === "number" ? value : Number(value);
183
- if (!Number.isInteger(length) || length < 0 || length > MAX_ARRAY_LENGTH)
184
- return false;
185
- target.items.length = length;
186
- return true;
187
- };
188
- /** [[Set]]: an inherited setter or read-only property decides before an own data property is created. */
189
- export const set = (target, key, value) => {
190
- const name = canonical(key);
191
- for (let current = target; current !== null; current = current.proto) {
192
- const slot = own(current, name);
193
- if (slot === undefined)
194
- continue;
195
- if (!("value" in slot)) {
196
- if (slot.set === undefined)
197
- return false;
198
- slot.set(target, value);
199
- return true;
200
- }
201
- if (!slot.writable)
99
+ if (name === "length" && target instanceof ProgramArray) {
100
+ const length = typeof value === "number" ? value : Number(value);
101
+ if (!Number.isInteger(length) || length < 0 || length > 4_294_967_295)
202
102
  return false;
203
- if (current !== target)
204
- break;
205
- if (target instanceof ProgramArray) {
206
- const written = writeArray(target, name, value);
207
- if (written !== undefined)
208
- return written;
209
- }
210
- slot.value = value;
103
+ target.items.length = length;
211
104
  return true;
212
105
  }
213
- if (target instanceof ProgramArray) {
214
- const written = writeArray(target, name, value);
215
- if (written !== undefined)
216
- return written;
217
- }
218
- target.props.set(name, { value, ...data });
106
+ if (builtin(target, name))
107
+ return false;
108
+ target.props.set(name, value);
219
109
  return true;
220
110
  };
221
- /** [[DefineOwnProperty]] for a data property, ignoring the chain. */
222
- export const define = (target, key, value, attrs = data) => {
223
- const name = canonical(key);
224
- if (target instanceof ProgramArray && writeArray(target, name, value) !== undefined)
225
- return;
226
- target.props.set(name, { value, ...attrs });
227
- };
228
- export const defineAccessor = (target, key, get, set) => {
229
- target.props.set(canonical(key), { get, set, enumerable: false, configurable: true });
230
- };
231
111
  export const remove = (target, key) => {
232
112
  const name = canonical(key);
233
- if (target instanceof ProgramArray) {
234
- const at = index(target, name);
235
- if (at !== undefined)
236
- return delete target.items[at];
237
- if (name === "length")
238
- return false;
239
- }
240
- const slot = target.props.get(name);
241
- if (slot === undefined)
242
- return true;
243
- if (!slot.configurable)
113
+ const at = index(target, name);
114
+ if (at !== undefined)
115
+ return delete target.items[at];
116
+ if (name === "length" && target instanceof ProgramArray)
244
117
  return false;
118
+ if (builtin(target, name))
119
+ return true;
245
120
  target.props.delete(name);
246
121
  return true;
247
122
  };
@@ -250,29 +125,27 @@ export const ownKeys = (target) => {
250
125
  const strings = [...target.props.keys()].filter((key) => typeof key === "string");
251
126
  const symbols = [...target.props.keys()].filter((key) => typeof key === "symbol");
252
127
  return [
253
- ...(target instanceof ProgramArray ? [...Object.keys(target.items), "length"] : []),
128
+ ...(target instanceof ProgramArray ? Object.keys(target.items) : []),
254
129
  ...strings.filter((key) => parseArrayIndex(key) !== undefined).sort((a, b) => Number(a) - Number(b)),
255
130
  ...strings.filter((key) => parseArrayIndex(key) === undefined),
256
131
  ...symbols,
257
132
  ];
258
133
  };
259
- const enumerable = (target, key) => own(target, key)?.enumerable === true;
260
- /** Own enumerable keys, including the iterator symbols; what spread and `Object.assign` copy. */
261
- export const enumerableKeys = (target) => ownKeys(target).filter((key) => (typeof key === "string" || key === IteratorSymbol || key === AsyncIteratorSymbol) && enumerable(target, key));
262
- /** Own enumerable string keys: `Object.keys`. */
263
- export const keys = (target) => ownKeys(target).filter((key) => typeof key === "string" && enumerable(target, key));
264
- /** Own enumerable string entries: `Object.entries` and serialization. */
265
- export const entries = (target) => keys(target).map((key) => [key, getOwn(target, key)]);
266
- export const record = (proto, fields) => {
267
- const target = new ProgramObject(proto);
268
- for (const [key, value] of Object.entries(fields))
269
- define(target, key, value);
134
+ export const ownEntries = (target) => ownKeys(target)
135
+ .filter((key) => typeof key === "string")
136
+ .map((key) => [key, getOwn(target, key)]);
137
+ export const record = (entries) => {
138
+ const target = new ProgramObject();
139
+ for (const [key, value] of Object.entries(entries))
140
+ set(target, key, value);
270
141
  return target;
271
142
  };
272
143
  export const assign = (target, source, skip) => {
273
- for (const key of enumerableKeys(source)) {
144
+ for (const key of ownKeys(source)) {
274
145
  if (skip?.has(key))
275
146
  continue;
147
+ if (typeof key === "symbol" && key !== IteratorSymbol && key !== AsyncIteratorSymbol)
148
+ continue;
276
149
  set(target, key, getOwn(source, key));
277
150
  }
278
151
  };