@poe-platform/safe-js 0.1.288 → 0.1.289

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/README.md CHANGED
@@ -103,8 +103,6 @@ Current-time reads are recorded for replay; replay does not call `now()` again.
103
103
 
104
104
  Date values copy by value across host bindings, preserving aliases within a graph. Checkpoints preserve epoch values, invalid dates and mutations rather than converting dates to strings. Parsing is limited to 4,096 characters and consumes the work/string budgets; retained values consume data budget. Local methods and non-ISO parsing follow the host timezone/runtime, so use explicit-zone ISO strings and UTC methods for portable output.
105
105
 
106
- Unsupported: locale formatting, legacy `getYear`/`setYear`/`toGMTString`, subclassing, custom argument coercion, Date-instance own properties and prototype modification. These are restrictions, not stubs; no native constructor or prototype is exposed to guest code.
107
-
108
106
  </details>
109
107
 
110
108
  ## Add a host capability
@@ -27,7 +27,7 @@ import {
27
27
  validateMigrationSemantics,
28
28
  validateSnapshotData,
29
29
  validateSnapshotMigration
30
- } from "./chunk-K45MDTVS.js";
30
+ } from "./chunk-KKMT52LR.js";
31
31
 
32
32
  // packages/safe-js/src/migrate.ts
33
33
  import { createHash } from "node:crypto";
@@ -8249,4 +8249,4 @@ export {
8249
8249
  parseMcpConfig,
8250
8250
  makeMcpModule
8251
8251
  };
8252
- //# sourceMappingURL=chunk-LOPY7ITQ.js.map
8252
+ //# sourceMappingURL=chunk-BNVOTMJ4.js.map
@@ -6966,6 +6966,9 @@ var methodNames = [
6966
6966
  "setUTCSeconds",
6967
6967
  "toDateString",
6968
6968
  "toISOString",
6969
+ "toLocaleString",
6970
+ "toLocaleDateString",
6971
+ "toLocaleTimeString",
6969
6972
  "toString",
6970
6973
  "toTimeString",
6971
6974
  "toUTCString",
@@ -20366,6 +20369,111 @@ async function parseJsonWithReviver(text, reviver, budget, context) {
20366
20369
  }
20367
20370
  }
20368
20371
 
20372
+ // packages/safe-js/src/interp/date-locale.ts
20373
+ var NativeDateTimeFormat = Intl.DateTimeFormat;
20374
+ var canonicalLocales = Intl.getCanonicalLocales;
20375
+ var dateTimeOptions = [
20376
+ ["localeMatcher", ["lookup", "best fit"]],
20377
+ ["calendar", "unicodeType"],
20378
+ ["numberingSystem", "unicodeType"],
20379
+ ["hour12", "boolean"],
20380
+ ["hourCycle", ["h11", "h12", "h23", "h24"]],
20381
+ ["timeZone", "zone"],
20382
+ ["weekday", ["narrow", "short", "long"]],
20383
+ ["era", ["narrow", "short", "long"]],
20384
+ ["year", ["2-digit", "numeric"]],
20385
+ ["month", ["2-digit", "numeric", "narrow", "short", "long"]],
20386
+ ["day", ["2-digit", "numeric"]],
20387
+ ["dayPeriod", ["narrow", "short", "long"]],
20388
+ ["hour", ["2-digit", "numeric"]],
20389
+ ["minute", ["2-digit", "numeric"]],
20390
+ ["second", ["2-digit", "numeric"]],
20391
+ ["fractionalSecondDigits", "number"],
20392
+ ["timeZoneName", ["short", "long", "shortOffset", "longOffset", "shortGeneric", "longGeneric"]],
20393
+ ["formatMatcher", ["basic", "best fit"]],
20394
+ ["dateStyle", ["full", "long", "medium", "short"]],
20395
+ ["timeStyle", ["full", "long", "medium", "short"]]
20396
+ ];
20397
+ async function formatDateLocale(name, time, args, budget, context) {
20398
+ if (Number.isNaN(time)) return budget.allocateString("Invalid Date");
20399
+ const locales = [];
20400
+ const options = /* @__PURE__ */ Object.create(null);
20401
+ const release = retainValues(budget, () => [locales, options]);
20402
+ const read = (value, key) => {
20403
+ budget.visitNode();
20404
+ if (context?.getProperty !== void 0) return context.getProperty(value, key);
20405
+ const descriptor = getSandboxPropertyDescriptor(value, key, budget);
20406
+ return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
20407
+ };
20408
+ const toObject = (value) => {
20409
+ if (value === null || value === void 0) throw new TypeError("Cannot convert null or undefined to an object.");
20410
+ if (typeof value === "object") return value;
20411
+ const box = createSandboxBox(value);
20412
+ allocateProducedSandboxValue(box, budget);
20413
+ return box;
20414
+ };
20415
+ try {
20416
+ const inputLocales = args[0];
20417
+ if (inputLocales !== void 0) {
20418
+ const list2 = typeof inputLocales === "string" ? [inputLocales] : toObject(inputLocales);
20419
+ const count = await sandboxNumber(await read(list2, "length"), budget, context);
20420
+ const length = Number.isNaN(count) || count <= 0 ? 0 : Math.min(Math.floor(count), Number.MAX_SAFE_INTEGER);
20421
+ for (let index = 0; index < length; index++) {
20422
+ budget.visitNode();
20423
+ const key = String(index);
20424
+ if (getSandboxPropertyDescriptor(list2, key, budget) === void 0 && !(isFloat32Array(list2) && Object.hasOwn(list2, key))) continue;
20425
+ const value = await read(list2, key);
20426
+ if (typeof value !== "string" && (typeof value !== "object" || value === null))
20427
+ throw new TypeError("Locale entries must be strings or objects.");
20428
+ const tag = await sandboxString(value, budget, context);
20429
+ budget.visitNode(tag.length);
20430
+ const canonical = canonicalLocales(tag)[0];
20431
+ budget.visitNode(locales.length);
20432
+ if (!locales.includes(canonical)) locales.push(budget.allocateString(canonical));
20433
+ }
20434
+ }
20435
+ const inputOptions = args[1] === void 0 ? /* @__PURE__ */ Object.create(null) : toObject(args[1]);
20436
+ for (const [key, type] of dateTimeOptions) {
20437
+ const value = await read(inputOptions, key);
20438
+ if (value === void 0) continue;
20439
+ if (type === "boolean") options[key] = Boolean(value);
20440
+ else if (type === "number") {
20441
+ const number = await sandboxNumber(value, budget, context);
20442
+ if (!Number.isFinite(number) || number < 1 || number > 3)
20443
+ throw new RangeError("fractionalSecondDigits must be between 1 and 3.");
20444
+ options[key] = Math.floor(number);
20445
+ } else {
20446
+ const text = await sandboxString(value, budget, context);
20447
+ budget.visitNode(text.length);
20448
+ if (type === "unicodeType") {
20449
+ const valid = text.split("-").every((part) => part.length >= 3 && part.length <= 8 && [...part].every((char) => char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char >= "0" && char <= "9"));
20450
+ if (!valid) throw new RangeError(`Invalid ${key} option.`);
20451
+ } else if (type === "zone") {
20452
+ new NativeDateTimeFormat("en", { timeZone: text });
20453
+ } else if (!type.includes(text)) throw new RangeError(`Invalid ${key} option.`);
20454
+ options[key] = text;
20455
+ }
20456
+ }
20457
+ const date = name !== "toLocaleTimeString";
20458
+ const clock = name !== "toLocaleDateString";
20459
+ if (options.dateStyle !== void 0 || options.timeStyle !== void 0) {
20460
+ if (!date && options.dateStyle !== void 0 || !clock && options.timeStyle !== void 0)
20461
+ throw new TypeError("Date/time style is incompatible with this locale method.");
20462
+ } else {
20463
+ const hasDate = date && ["weekday", "year", "month", "day"].some((key) => options[key] !== void 0);
20464
+ const hasTime = clock && ["dayPeriod", "hour", "minute", "second", "fractionalSecondDigits"].some((key) => options[key] !== void 0);
20465
+ if (!hasDate && !hasTime) {
20466
+ if (date) for (const key of ["year", "month", "day"]) options[key] = "numeric";
20467
+ if (clock) for (const key of ["hour", "minute", "second"]) options[key] = "numeric";
20468
+ }
20469
+ }
20470
+ const formatter = new NativeDateTimeFormat(locales, options);
20471
+ return budget.allocateString(formatter.format(time));
20472
+ } finally {
20473
+ release();
20474
+ }
20475
+ }
20476
+
20369
20477
  // packages/safe-js/src/snapshot/replay-data.ts
20370
20478
  var MissingReplayCapabilityError = class extends TypeError {
20371
20479
  };
@@ -21943,6 +22051,7 @@ function createDateGlobal(options) {
21943
22051
  if (!isSandboxDate(receiver))
21944
22052
  throw new TypeError(`Date#${name} requires a Date receiver.`);
21945
22053
  options.budget.visitNode();
22054
+ if (name.startsWith("toLocale")) return formatDateLocale(name, dateTime(receiver), args, options.budget, context);
21946
22055
  if (name.startsWith("set")) return coerceDateSetter(name, receiver, args, options.budget, context);
21947
22056
  const value = method.invoke(receiver, args);
21948
22057
  return typeof value === "string" ? options.budget.allocateString(value) : value;
@@ -40340,4 +40449,4 @@ export {
40340
40449
  FileSnapshotBackend,
40341
40450
  run
40342
40451
  };
40343
- //# sourceMappingURL=chunk-K45MDTVS.js.map
40452
+ //# sourceMappingURL=chunk-KKMT52LR.js.map