@opencode/codemode 0.0.0-dev-20151 → 0.0.0-dev-20155

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.
@@ -2,7 +2,7 @@ import { Effect } from "effect";
2
2
  import { Arr, Callable, coerceToInteger, coerceToString, get, Obj } from "./objects.js";
3
3
  import { arrayGlobal } from "../stdlib/array.js";
4
4
  import { textDecoderGlobal, textEncoderGlobal, uint8ArrayGlobal } from "../stdlib/bytes.js";
5
- import { mapGlobal, setGlobal } from "../stdlib/collections.js";
5
+ import { mapGlobal, setGlobal, weakMapGlobal, weakSetGlobal } from "../stdlib/collections.js";
6
6
  import { consoleGlobal } from "../stdlib/console.js";
7
7
  import { dateGlobal } from "../stdlib/date.js";
8
8
  import { jsonGlobal } from "../stdlib/json.js";
@@ -104,6 +104,8 @@ const table = {
104
104
  RegExp: (ctx) => regexpGlobal(ctx),
105
105
  Map: (ctx) => mapGlobal(ctx),
106
106
  Set: (ctx) => setGlobal(ctx),
107
+ WeakMap: (ctx) => weakMapGlobal(ctx),
108
+ WeakSet: (ctx) => weakSetGlobal(ctx),
107
109
  URL: (ctx) => urlGlobal(ctx),
108
110
  URLSearchParams: (ctx) => urlSearchParamsGlobal(ctx),
109
111
  Headers: (ctx) => headersGlobal(ctx),
@@ -2,7 +2,7 @@ import { ErrorObj, Obj, type Value } from "./objects.js";
2
2
  export declare const errorTypes: readonly ["Error", "TypeError", "RangeError", "SyntaxError", "ReferenceError", "EvalError", "URIError", "AggregateError"];
3
3
  export type ErrorType = (typeof errorTypes)[number];
4
4
  export declare const isErrorType: (name: string) => name is ErrorType;
5
- declare const builtins: readonly ["Object", "Function", "Array", "String", "Number", "Boolean", "Date", "RegExp", "Map", "Set", "URL", "URLSearchParams", "Headers", "Uint8Array", "TextEncoder", "TextDecoder", "Promise", "Iterator", "IteratorHelper", "AsyncIterator", "Generator", "AsyncGenerator"];
5
+ declare const builtins: readonly ["Object", "Function", "Array", "String", "Number", "Boolean", "Date", "RegExp", "Map", "Set", "WeakMap", "WeakSet", "URL", "URLSearchParams", "Headers", "Uint8Array", "TextEncoder", "TextDecoder", "Promise", "Iterator", "IteratorHelper", "AsyncIterator", "Generator", "AsyncGenerator"];
6
6
  /**
7
7
  * The built-in prototype objects of one runtime, allocated empty in dependency order. The globals populate them
8
8
  * and attach their constructors when the runtime is built.
@@ -22,6 +22,8 @@ const builtins = [
22
22
  "RegExp",
23
23
  "Map",
24
24
  "Set",
25
+ "WeakMap",
26
+ "WeakSet",
25
27
  "URL",
26
28
  "URLSearchParams",
27
29
  "Headers",
@@ -78,6 +80,8 @@ export const createBuiltins = () => {
78
80
  RegExp: plain(),
79
81
  Map: plain(),
80
82
  Set: plain(),
83
+ WeakMap: plain(),
84
+ WeakSet: plain(),
81
85
  URL: plain(),
82
86
  URLSearchParams: plain(),
83
87
  Headers: plain(),
@@ -192,6 +192,17 @@ export declare class SetObj extends Wrapper {
192
192
  toHost(item: (value: Value) => unknown): Set<unknown>;
193
193
  iterator(): SetIterator<Value>;
194
194
  }
195
+ /** Keys are program objects, so a host WeakMap gives the same lifetime rule as JavaScript without any bookkeeping. */
196
+ export declare class WeakMapObj extends Wrapper {
197
+ readonly tag = "WeakMap";
198
+ readonly map: WeakMap<Obj, Value>;
199
+ inspect(): string;
200
+ }
201
+ export declare class WeakSetObj extends Wrapper {
202
+ readonly tag = "WeakSet";
203
+ readonly set: WeakSet<Obj>;
204
+ inspect(): string;
205
+ }
195
206
  export declare class URLSearchParamsObj extends Wrapper {
196
207
  readonly params: URLSearchParams;
197
208
  readonly tag = "URLSearchParams";
@@ -281,6 +281,21 @@ export class SetObj extends Wrapper {
281
281
  return this.set.values();
282
282
  }
283
283
  }
284
+ /** Keys are program objects, so a host WeakMap gives the same lifetime rule as JavaScript without any bookkeeping. */
285
+ export class WeakMapObj extends Wrapper {
286
+ tag = "WeakMap";
287
+ map = new WeakMap();
288
+ inspect() {
289
+ return "WeakMap { <items unknown> }";
290
+ }
291
+ }
292
+ export class WeakSetObj extends Wrapper {
293
+ tag = "WeakSet";
294
+ set = new WeakSet();
295
+ inspect() {
296
+ return "WeakSet { <items unknown> }";
297
+ }
298
+ }
284
299
  export class URLSearchParamsObj extends Wrapper {
285
300
  params;
286
301
  tag = "URLSearchParams";
@@ -3,3 +3,5 @@ import type { Interpreter } from "../interpreter/interpreter.js";
3
3
  export declare const groupBy: <R>(ctx: Interpreter<R>, namespace: "Map" | "Object") => import("../interpreter/objects.js").Native<R>;
4
4
  export declare const mapGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
5
5
  export declare const setGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
6
+ export declare const weakMapGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
7
+ export declare const weakSetGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
2
  import { constructor, fn, methods, prototypeFrom, receiver, requiresNew } from "../interpreter/native.js";
3
3
  import { invalidData, IteratorSymbol, typeError } from "../interpreter/model.js";
4
- import { define, defineAccessor, get, getOwn, hidden, Arr, coerceToString, hostCursor, hostIterator, MapObj, Obj, PromiseObj, SetObj, } from "../interpreter/objects.js";
4
+ import { define, defineAccessor, get, getOwn, hidden, Arr, coerceToString, hostCursor, hostIterator, MapObj, Obj, PromiseObj, SetObj, WeakMapObj, WeakSetObj, } from "../interpreter/objects.js";
5
5
  import { describeValue, isOpaque } from "../interpreter/references.js";
6
6
  import { applyCollectionCallback, isSupportedCallback, preserveConsumerError, toPrimitiveNumber, toPrimitiveString, } from "../interpreter/callback.js";
7
7
  const coerceGroupByPropertyKey = (ctx, value) => {
@@ -373,3 +373,130 @@ export const setGlobal = (ctx) => {
373
373
  define(proto, IteratorSymbol, get(proto, "values"), hidden);
374
374
  return set;
375
375
  };
376
+ // CanBeHeldWeakly: only program objects; tool references are rebuilt on every access, so they could never be found again.
377
+ const weakKey = (value, label) => {
378
+ if (value instanceof Obj)
379
+ return value;
380
+ throw typeError(`Invalid value used ${label}: ${describeValue(value)} cannot be held weakly.`);
381
+ };
382
+ export const weakMapGlobal = (ctx) => {
383
+ const builtins = ctx.builtins;
384
+ const proto = builtins.WeakMap;
385
+ const weakMap = constructor(builtins, proto, {
386
+ name: "WeakMap",
387
+ call: requiresNew("WeakMap"),
388
+ construct: (args, newTarget) => {
389
+ const target = new WeakMapObj(prototypeFrom(newTarget, proto));
390
+ if (args[0] === undefined || args[0] === null)
391
+ return Effect.succeed(target);
392
+ return Effect.gen(function* () {
393
+ const cursor = yield* ctx.iterate(args[0]);
394
+ if (cursor === undefined) {
395
+ throw typeError(`new WeakMap(...) expects an iterable of [key, value] pairs, received ${describeValue(args[0])}.`);
396
+ }
397
+ while (true) {
398
+ const step = yield* cursor.next;
399
+ if (step.done)
400
+ return target;
401
+ yield* preserveConsumerError(cursor.close, Effect.sync(() => {
402
+ if (!(step.value instanceof Obj)) {
403
+ throw typeError("new WeakMap(...) expects [key, value] pairs as entry objects.");
404
+ }
405
+ target.map.set(weakKey(getOwn(step.value, 0), "as weak map key"), getOwn(step.value, 1));
406
+ }));
407
+ }
408
+ });
409
+ },
410
+ });
411
+ const self = (thisValue, name) => receiver(WeakMapObj, thisValue, `WeakMap.prototype.${name}`).map;
412
+ // Lookups pass any key through: the host collection answers false for a non-object, as the spec requires.
413
+ const key = (value) => weakKey(value, "as weak map key");
414
+ methods(builtins, proto, [
415
+ [
416
+ "get",
417
+ 1,
418
+ (thisValue, args) => {
419
+ const target = self(thisValue, "get");
420
+ return args[0] instanceof Obj ? target.get(args[0]) : undefined;
421
+ },
422
+ ],
423
+ ["has", 1, (thisValue, args) => self(thisValue, "has").has(args[0])],
424
+ ["delete", 1, (thisValue, args) => self(thisValue, "delete").delete(args[0])],
425
+ [
426
+ "set",
427
+ 2,
428
+ (thisValue, args) => {
429
+ self(thisValue, "set").set(key(args[0]), args[1]);
430
+ return thisValue;
431
+ },
432
+ ],
433
+ [
434
+ "getOrInsert",
435
+ 2,
436
+ (thisValue, args) => {
437
+ const target = self(thisValue, "getOrInsert");
438
+ const k = key(args[0]);
439
+ if (!target.has(k))
440
+ target.set(k, args[1]);
441
+ return target.get(k);
442
+ },
443
+ ],
444
+ [
445
+ "getOrInsertComputed",
446
+ 2,
447
+ (thisValue, args) => {
448
+ const target = self(thisValue, "getOrInsertComputed");
449
+ const k = key(args[0]);
450
+ const apply = applyCollectionCallback(ctx, args[1], "WeakMap.getOrInsertComputed");
451
+ if (target.has(k))
452
+ return target.get(k);
453
+ return Effect.map(apply([k]), (value) => {
454
+ target.set(k, value);
455
+ return value;
456
+ });
457
+ },
458
+ ],
459
+ ]);
460
+ return weakMap;
461
+ };
462
+ export const weakSetGlobal = (ctx) => {
463
+ const builtins = ctx.builtins;
464
+ const proto = builtins.WeakSet;
465
+ const weakSet = constructor(builtins, proto, {
466
+ name: "WeakSet",
467
+ call: requiresNew("WeakSet"),
468
+ construct: (args, newTarget) => {
469
+ const target = new WeakSetObj(prototypeFrom(newTarget, proto));
470
+ if (args[0] === undefined || args[0] === null)
471
+ return Effect.succeed(target);
472
+ return Effect.gen(function* () {
473
+ const cursor = yield* ctx.iterate(args[0]);
474
+ if (cursor === undefined) {
475
+ throw typeError(`new WeakSet(...) expects a synchronous iterable, received ${describeValue(args[0])}.`);
476
+ }
477
+ while (true) {
478
+ const step = yield* cursor.next;
479
+ if (step.done)
480
+ return target;
481
+ yield* preserveConsumerError(cursor.close, Effect.sync(() => {
482
+ target.set.add(weakKey(step.value, "in weak set"));
483
+ }));
484
+ }
485
+ });
486
+ },
487
+ });
488
+ const self = (thisValue, name) => receiver(WeakSetObj, thisValue, `WeakSet.prototype.${name}`).set;
489
+ methods(builtins, proto, [
490
+ ["has", 1, (thisValue, args) => self(thisValue, "has").has(args[0])],
491
+ ["delete", 1, (thisValue, args) => self(thisValue, "delete").delete(args[0])],
492
+ [
493
+ "add",
494
+ 1,
495
+ (thisValue, args) => {
496
+ self(thisValue, "add").add(weakKey(args[0], "in weak set"));
497
+ return thisValue;
498
+ },
499
+ ],
500
+ ]);
501
+ return weakSet;
502
+ };
@@ -1,6 +1,6 @@
1
1
  import { fn, methods } from "../interpreter/native.js";
2
2
  import { typeError } from "../interpreter/model.js";
3
- import { define, entries, get, getOwn, hasOwn, hidden, isRuntimeReference, Arr, Bytes, DateObj, ErrorObj, MapObj, Obj, RegExpObj, SetObj, coerceToString, } from "../interpreter/objects.js";
3
+ import { define, entries, get, getOwn, hasOwn, hidden, isRuntimeReference, Arr, Bytes, DateObj, ErrorObj, MapObj, Obj, RegExpObj, SetObj, WeakMapObj, WeakSetObj, coerceToString, } from "../interpreter/objects.js";
4
4
  import { createErrorValue, isErrorType } from "../interpreter/intrinsics.js";
5
5
  import { describeValue } from "../interpreter/references.js";
6
6
  import { ToolReference } from "../tool-runtime.js";
@@ -67,8 +67,9 @@ export const structuredCloneGlobal = (ctx) => fn(ctx.builtins, "structuredClone"
67
67
  define(copy, "cause", clone(getOwn(value, "cause")), hidden);
68
68
  return copy;
69
69
  }
70
- if (isRuntimeReference(value))
70
+ if (isRuntimeReference(value) || value instanceof WeakMapObj || value instanceof WeakSetObj) {
71
71
  throw typeError(`DataCloneError: ${describeValue(value)} could not be cloned.`);
72
+ }
72
73
  const copy = remember(value instanceof Arr ? new Arr(builtins.Array, new Array(value.items.length)) : new Obj(builtins.Object));
73
74
  for (const [key, item] of entries(value))
74
75
  define(copy, key, clone(item));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@opencode/codemode",
4
- "version": "0.0.0-dev-20151",
4
+ "version": "0.0.0-dev-20155",
5
5
  "description": "Effect-native confined code execution over schema-described tools",
6
6
  "type": "module",
7
7
  "license": "MIT",