683 lines
24 KiB
JavaScript
683 lines
24 KiB
JavaScript
// This polyfill is executed in a vm.Script context by test262-runner,
|
|
// so it must be synchronous and self-contained.
|
|
// The wasm bytes are injected as global.__TEMPORALZ_WASM_BYTES__ by the runner.
|
|
(function () {
|
|
if (!globalThis.__TEMPORALZ_WASM_BYTES__) {
|
|
throw new Error("WASM bytes not injected into test context");
|
|
}
|
|
|
|
const wasmBinary = globalThis.__TEMPORALZ_WASM_BYTES__;
|
|
const wasmModule = new WebAssembly.Module(wasmBinary);
|
|
const wasmInstance = new WebAssembly.Instance(wasmModule, {
|
|
env: {
|
|
console(ptr, len) {
|
|
const bytes = new Uint8Array(memory.buffer, ptr, len);
|
|
globalThis.console.log(decoder.decode(bytes));
|
|
},
|
|
},
|
|
});
|
|
|
|
const exports = wasmInstance.exports;
|
|
const memory = exports.memory;
|
|
|
|
const encoder = {
|
|
encode(str) {
|
|
const buf = [];
|
|
for (let i = 0; i < str.length; i++) {
|
|
const code = str.charCodeAt(i);
|
|
if (code < 0x80) {
|
|
buf.push(code);
|
|
} else if (code < 0x800) {
|
|
buf.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
|
|
} else if (code < 0xd800 || code >= 0xe000) {
|
|
buf.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
|
|
} else {
|
|
const code2 = str.charCodeAt(++i);
|
|
const codePoint = 0x10000 + (((code & 0x3ff) << 10) | (code2 & 0x3ff));
|
|
buf.push(
|
|
0xf0 | (codePoint >> 18),
|
|
0x80 | ((codePoint >> 12) & 0x3f),
|
|
0x80 | ((codePoint >> 6) & 0x3f),
|
|
0x80 | (codePoint & 0x3f)
|
|
);
|
|
}
|
|
}
|
|
return new Uint8Array(buf);
|
|
},
|
|
};
|
|
|
|
const decoder = {
|
|
decode(bytes) {
|
|
let str = "";
|
|
for (let i = 0; i < bytes.length; i++) {
|
|
const byte = bytes[i];
|
|
if (byte < 0x80) {
|
|
str += String.fromCharCode(byte);
|
|
} else if ((byte & 0xe0) === 0xc0) {
|
|
str += String.fromCharCode(((byte & 0x1f) << 6) | (bytes[++i] & 0x3f));
|
|
} else if ((byte & 0xf0) === 0xe0) {
|
|
str += String.fromCharCode(
|
|
((byte & 0x0f) << 12) | ((bytes[++i] & 0x3f) << 6) | (bytes[++i] & 0x3f)
|
|
);
|
|
} else if ((byte & 0xf8) === 0xf0) {
|
|
const codePoint =
|
|
((byte & 0x07) << 18) |
|
|
((bytes[++i] & 0x3f) << 12) |
|
|
((bytes[++i] & 0x3f) << 6) |
|
|
(bytes[++i] & 0x3f);
|
|
const high = ((codePoint - 0x10000) >> 10) + 0xd800;
|
|
const low = ((codePoint - 0x10000) & 0x3ff) + 0xdc00;
|
|
str += String.fromCharCode(high, low);
|
|
}
|
|
}
|
|
return str;
|
|
},
|
|
};
|
|
|
|
function readString(ptr, len) {
|
|
return decoder.decode(new Uint8Array(memory.buffer, ptr, len));
|
|
}
|
|
|
|
function lastError() {
|
|
const ptr = exports.temporalz_last_error_ptr();
|
|
const len = exports.temporalz_last_error_len();
|
|
if (!ptr || !len) return new Error("temporalz error");
|
|
const msg = readString(ptr, len);
|
|
exports.temporalz_last_error_clear();
|
|
if (msg.includes("Range")) return new RangeError(msg);
|
|
if (msg.includes("Type")) return new TypeError(msg);
|
|
return new Error(msg);
|
|
}
|
|
|
|
function requireHandle(handle) {
|
|
if (!handle) throw lastError();
|
|
return handle;
|
|
}
|
|
|
|
function allocString(text) {
|
|
const bytes = encoder.encode(text);
|
|
const ptr = exports.temporalz_alloc(bytes.length);
|
|
if (!ptr) throw lastError();
|
|
new Uint8Array(memory.buffer, ptr, bytes.length).set(bytes);
|
|
return { ptr, len: bytes.length };
|
|
}
|
|
|
|
function takeString(packed) {
|
|
if (!packed) throw lastError();
|
|
const value = BigInt(packed);
|
|
const ptr = Number(value >> 32n);
|
|
const len = Number(value & 0xffffffffn);
|
|
const text = readString(ptr, len);
|
|
exports.temporalz_string_free(ptr, len);
|
|
return text;
|
|
}
|
|
|
|
function splitI128(value) {
|
|
const v = typeof value === "bigint" ? value : BigInt(value);
|
|
const mask = (1n << 64n) - 1n;
|
|
return { hi: v >> 64n, lo: v & mask };
|
|
}
|
|
|
|
function joinI128(hi, lo) {
|
|
const mask = (1n << 64n) - 1n;
|
|
return (BigInt(hi) << 64n) | (BigInt(lo) & mask);
|
|
}
|
|
|
|
const unitCodes = {
|
|
nanosecond: 1,
|
|
microsecond: 2,
|
|
millisecond: 3,
|
|
second: 4,
|
|
minute: 5,
|
|
hour: 6,
|
|
day: 7,
|
|
week: 8,
|
|
month: 9,
|
|
year: 10,
|
|
auto: 11,
|
|
};
|
|
|
|
const roundingModeCodes = {
|
|
ceil: 1,
|
|
floor: 2,
|
|
expand: 3,
|
|
trunc: 4,
|
|
halfCeil: 5,
|
|
halfFloor: 6,
|
|
halfExpand: 7,
|
|
halfTrunc: 8,
|
|
halfEven: 9,
|
|
};
|
|
|
|
function toUnitCode(value, name) {
|
|
if (value === undefined || value === null) return 255;
|
|
const code = unitCodes[value];
|
|
if (!code) throw new RangeError(`Invalid ${name}`);
|
|
return code;
|
|
}
|
|
|
|
function toRoundingModeCode(value) {
|
|
if (value === undefined || value === null) return 255;
|
|
const code = roundingModeCodes[value];
|
|
if (!code) throw new RangeError("Invalid roundingMode");
|
|
return code;
|
|
}
|
|
|
|
function toIntegerBigInt(value, name) {
|
|
if (typeof value === "bigint") return value;
|
|
const number = Number(value);
|
|
if (!isFiniteNumber(number)) throw new RangeError(`${name} must be finite`);
|
|
if (!Number.isInteger(number)) throw new RangeError(`${name} must be an integer`);
|
|
return BigInt(number);
|
|
}
|
|
|
|
function toNumber(value, name) {
|
|
const number = Number(value);
|
|
if (!isFiniteNumber(number)) throw new RangeError(`${name} must be finite`);
|
|
return number;
|
|
}
|
|
|
|
function toInteger(value, name) {
|
|
const number = Number(value);
|
|
if (!isFiniteNumber(number)) throw new RangeError(`${name} must be finite`);
|
|
if (!Number.isInteger(number)) throw new RangeError(`${name} must be an integer`);
|
|
return number;
|
|
}
|
|
|
|
function isFiniteNumber(value) {
|
|
return value === value && value !== Infinity && value !== -Infinity;
|
|
}
|
|
|
|
function unimplemented(name) {
|
|
return function () {
|
|
throw new Error(`${name} is not implemented yet`);
|
|
};
|
|
}
|
|
|
|
class Instant {
|
|
constructor(handle) {
|
|
this._handle = handle;
|
|
}
|
|
|
|
static _fromHandle(handle) {
|
|
return new Instant(handle);
|
|
}
|
|
|
|
static fromEpochMilliseconds(epochMs) {
|
|
const number = Number(epochMs);
|
|
if (!isFiniteNumber(number)) throw new RangeError("epochMilliseconds must be finite");
|
|
const handle = exports.temporalz_instant_from_epoch_milliseconds(number);
|
|
return Instant._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
static fromEpochNanoseconds(epochNs) {
|
|
const parts = splitI128(epochNs);
|
|
const handle = exports.temporalz_instant_from_epoch_nanoseconds_parts(
|
|
parts.hi,
|
|
parts.lo
|
|
);
|
|
return Instant._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
static from(value) {
|
|
if (value instanceof Instant) return value;
|
|
if (typeof value === "string") {
|
|
const text = allocString(value);
|
|
const handle = exports.temporalz_instant_from_utf8(text.ptr, text.len);
|
|
exports.temporalz_free(text.ptr, text.len);
|
|
return Instant._fromHandle(requireHandle(handle));
|
|
}
|
|
if (value && typeof value === "object") {
|
|
if (value.epochNanoseconds !== undefined) {
|
|
return Instant.fromEpochNanoseconds(value.epochNanoseconds);
|
|
}
|
|
if (value.epochMilliseconds !== undefined) {
|
|
return Instant.fromEpochMilliseconds(value.epochMilliseconds);
|
|
}
|
|
}
|
|
throw new TypeError("Instant.from expects a string or object");
|
|
}
|
|
|
|
get epochMilliseconds() {
|
|
return exports.temporalz_instant_epoch_milliseconds(this._handle);
|
|
}
|
|
|
|
get epochNanoseconds() {
|
|
const hi = exports.temporalz_instant_epoch_nanoseconds_hi(this._handle);
|
|
const lo = exports.temporalz_instant_epoch_nanoseconds_lo(this._handle);
|
|
return joinI128(hi, lo);
|
|
}
|
|
|
|
toString() {
|
|
return takeString(exports.temporalz_instant_to_string(this._handle));
|
|
}
|
|
|
|
toJSON() {
|
|
return this.toString();
|
|
}
|
|
|
|
add(durationLike) {
|
|
const dur = Duration.from(durationLike);
|
|
const handle = exports.temporalz_instant_add(this._handle, dur._handle);
|
|
return Instant._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
subtract(durationLike) {
|
|
const dur = Duration.from(durationLike);
|
|
const handle = exports.temporalz_instant_subtract(this._handle, dur._handle);
|
|
return Instant._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
round(options) {
|
|
if (!options || typeof options !== "object") {
|
|
throw new TypeError("round options must be an object");
|
|
}
|
|
const smallestUnit = toUnitCode(options.smallestUnit, "smallestUnit");
|
|
if (smallestUnit === 255) throw new RangeError("smallestUnit is required");
|
|
const roundingMode = toRoundingModeCode(options.roundingMode);
|
|
|
|
let roundingIncrement = 0;
|
|
if (options.roundingIncrement !== undefined) {
|
|
const inc = Number(options.roundingIncrement);
|
|
if (!isFiniteNumber(inc) || !Number.isInteger(inc) || inc <= 0) {
|
|
throw new RangeError("Invalid roundingIncrement");
|
|
}
|
|
roundingIncrement = inc;
|
|
}
|
|
|
|
const handle = exports.temporalz_instant_round(
|
|
this._handle,
|
|
smallestUnit,
|
|
roundingMode,
|
|
roundingIncrement
|
|
);
|
|
return Instant._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
equals(other) {
|
|
const rhs = Instant.from(other);
|
|
return exports.temporalz_instant_equals(this._handle, rhs._handle) === 1;
|
|
}
|
|
|
|
toLocaleString() {
|
|
return this.toString();
|
|
}
|
|
|
|
valueOf() {
|
|
throw new TypeError("Cannot convert Temporal.Instant to a number");
|
|
}
|
|
|
|
static compare(a, b) {
|
|
const left = Instant.from(a);
|
|
const right = Instant.from(b);
|
|
return Number(exports.temporalz_instant_compare(left._handle, right._handle));
|
|
}
|
|
}
|
|
|
|
const plainDateHandleToken = Symbol("PlainDateHandle");
|
|
|
|
class PlainDate {
|
|
constructor(year, month, day) {
|
|
if (year === plainDateHandleToken) {
|
|
this._handle = month;
|
|
return;
|
|
}
|
|
|
|
const yearValue = toInteger(year ?? 0, "year");
|
|
const monthValue = toInteger(month ?? 0, "month");
|
|
const dayValue = toInteger(day ?? 0, "day");
|
|
const handle = exports.temporalz_plain_date_init(yearValue, monthValue, dayValue);
|
|
this._handle = requireHandle(handle);
|
|
}
|
|
|
|
static _fromHandle(handle) {
|
|
return new PlainDate(plainDateHandleToken, handle);
|
|
}
|
|
|
|
static from(value) {
|
|
if (value instanceof PlainDate) return value;
|
|
if (typeof value === "string") {
|
|
const text = allocString(value);
|
|
const handle = exports.temporalz_plain_date_from_utf8(text.ptr, text.len);
|
|
exports.temporalz_free(text.ptr, text.len);
|
|
return PlainDate._fromHandle(requireHandle(handle));
|
|
}
|
|
if (value === null || typeof value !== "object") {
|
|
throw new TypeError("PlainDate.from expects a string or object");
|
|
}
|
|
|
|
const year = toInteger(value.year, "year");
|
|
const month = toInteger(value.month, "month");
|
|
const day = toInteger(value.day, "day");
|
|
const handle = exports.temporalz_plain_date_init(year, month, day);
|
|
return PlainDate._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
toString() {
|
|
return takeString(exports.temporalz_plain_date_to_string(this._handle));
|
|
}
|
|
}
|
|
|
|
const durationHandleToken = Symbol("DurationHandle");
|
|
|
|
class Duration {
|
|
constructor(
|
|
years,
|
|
months,
|
|
weeks,
|
|
days,
|
|
hours,
|
|
minutes,
|
|
seconds,
|
|
milliseconds,
|
|
microseconds,
|
|
nanoseconds
|
|
) {
|
|
if (years === durationHandleToken) {
|
|
this._handle = months;
|
|
return;
|
|
}
|
|
|
|
const yearsValue = toIntegerBigInt(years ?? 0, "years");
|
|
const monthsValue = toIntegerBigInt(months ?? 0, "months");
|
|
const weeksValue = toIntegerBigInt(weeks ?? 0, "weeks");
|
|
const daysValue = toIntegerBigInt(days ?? 0, "days");
|
|
const hoursValue = toIntegerBigInt(hours ?? 0, "hours");
|
|
const minutesValue = toIntegerBigInt(minutes ?? 0, "minutes");
|
|
const secondsValue = toIntegerBigInt(seconds ?? 0, "seconds");
|
|
const millisecondsValue = toIntegerBigInt(milliseconds ?? 0, "milliseconds");
|
|
const microsecondsValue = toNumber(microseconds ?? 0, "microseconds");
|
|
const nanosecondsValue = toNumber(nanoseconds ?? 0, "nanoseconds");
|
|
|
|
const created = exports.temporalz_duration_init(
|
|
yearsValue,
|
|
monthsValue,
|
|
weeksValue,
|
|
daysValue,
|
|
hoursValue,
|
|
minutesValue,
|
|
secondsValue,
|
|
millisecondsValue,
|
|
microsecondsValue,
|
|
nanosecondsValue
|
|
);
|
|
this._handle = requireHandle(created);
|
|
}
|
|
|
|
static _fromHandle(handle) {
|
|
return new Duration(durationHandleToken, handle);
|
|
}
|
|
|
|
static from(value) {
|
|
if (value instanceof Duration) return value;
|
|
if (typeof value === "string") {
|
|
const text = allocString(value);
|
|
const handle = exports.temporalz_duration_from_utf8(text.ptr, text.len);
|
|
exports.temporalz_free(text.ptr, text.len);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
if (value === null || typeof value !== "object") {
|
|
throw new TypeError("Duration.from expects a string or object");
|
|
}
|
|
|
|
const fields = [
|
|
"years",
|
|
"months",
|
|
"weeks",
|
|
"days",
|
|
"hours",
|
|
"minutes",
|
|
"seconds",
|
|
"milliseconds",
|
|
"microseconds",
|
|
"nanoseconds",
|
|
];
|
|
|
|
let mask = 0;
|
|
const values = [0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0, 0];
|
|
|
|
fields.forEach((field, index) => {
|
|
if (value[field] !== undefined) {
|
|
mask |= 1 << index;
|
|
if (field === "microseconds" || field === "nanoseconds") {
|
|
values[index] = toNumber(value[field], field);
|
|
} else {
|
|
values[index] = toIntegerBigInt(value[field], field);
|
|
}
|
|
}
|
|
});
|
|
|
|
const handle = exports.temporalz_duration_from_parts(
|
|
mask,
|
|
values[0],
|
|
values[1],
|
|
values[2],
|
|
values[3],
|
|
values[4],
|
|
values[5],
|
|
values[6],
|
|
values[7],
|
|
values[8],
|
|
values[9]
|
|
);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
static compare(a, b, options) {
|
|
const left = Duration.from(a);
|
|
const right = Duration.from(b);
|
|
return Duration.compareWithOptions(left, right, options);
|
|
}
|
|
|
|
static compareWithOptions(left, right, options) {
|
|
if (options !== undefined && (options === null || typeof options !== "object")) {
|
|
throw new TypeError("options must be an object");
|
|
}
|
|
const relativeTo = toRelativeTo(options);
|
|
if (!relativeTo && (hasYearMonthWeek(left) || hasYearMonthWeek(right))) {
|
|
throw new RangeError("relativeTo is required for calendar units");
|
|
}
|
|
if (relativeTo) {
|
|
return Number(
|
|
exports.temporalz_duration_compare_plain_date(
|
|
left._handle,
|
|
right._handle,
|
|
relativeTo._handle
|
|
)
|
|
);
|
|
}
|
|
return Number(exports.temporalz_duration_compare(left._handle, right._handle));
|
|
}
|
|
|
|
add(other) {
|
|
const rhs = Duration.from(other);
|
|
const handle = exports.temporalz_duration_add(this._handle, rhs._handle);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
subtract(other) {
|
|
const rhs = Duration.from(other);
|
|
const handle = exports.temporalz_duration_subtract(this._handle, rhs._handle);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
abs() {
|
|
const handle = exports.temporalz_duration_abs(this._handle);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
negated() {
|
|
const handle = exports.temporalz_duration_negated(this._handle);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
round(options = {}) {
|
|
if (options === undefined) options = {};
|
|
if (options === null || typeof options !== "object") {
|
|
throw new TypeError("round options must be an object");
|
|
}
|
|
const relativeTo = toRelativeTo(options);
|
|
if (!relativeTo && hasCalendarUnits(this)) {
|
|
throw new RangeError("relativeTo is required for calendar units");
|
|
}
|
|
const smallestUnit = toUnitCode(options.smallestUnit, "smallestUnit");
|
|
const largestUnit = toUnitCode(options.largestUnit, "largestUnit");
|
|
const roundingMode = toRoundingModeCode(options.roundingMode);
|
|
|
|
let roundingIncrement = 0;
|
|
if (options.roundingIncrement !== undefined) {
|
|
const inc = Number(options.roundingIncrement);
|
|
if (!Number.isFinite(inc) || !Number.isInteger(inc) || inc <= 0) {
|
|
throw new RangeError("Invalid roundingIncrement");
|
|
}
|
|
roundingIncrement = inc;
|
|
}
|
|
|
|
const handle = relativeTo
|
|
? exports.temporalz_duration_round_plain_date(
|
|
this._handle,
|
|
smallestUnit,
|
|
largestUnit,
|
|
roundingMode,
|
|
roundingIncrement,
|
|
relativeTo._handle
|
|
)
|
|
: exports.temporalz_duration_round(
|
|
this._handle,
|
|
smallestUnit,
|
|
largestUnit,
|
|
roundingMode,
|
|
roundingIncrement
|
|
);
|
|
return Duration._fromHandle(requireHandle(handle));
|
|
}
|
|
|
|
total(options) {
|
|
if (!options || typeof options !== "object") {
|
|
throw new TypeError("total options must be an object");
|
|
}
|
|
const relativeTo = toRelativeTo(options);
|
|
if (!relativeTo && hasCalendarUnits(this)) {
|
|
throw new RangeError("relativeTo is required for calendar units");
|
|
}
|
|
const unit = toUnitCode(options.unit, "unit");
|
|
if (unit === 255) throw new RangeError("Invalid unit");
|
|
const result = relativeTo
|
|
? exports.temporalz_duration_total_plain_date(
|
|
this._handle,
|
|
unit,
|
|
relativeTo._handle
|
|
)
|
|
: exports.temporalz_duration_total(this._handle, unit);
|
|
if (!Number.isFinite(result)) throw lastError();
|
|
return result;
|
|
}
|
|
|
|
get sign() {
|
|
return Number(exports.temporalz_duration_sign(this._handle));
|
|
}
|
|
|
|
get blank() {
|
|
return exports.temporalz_duration_blank(this._handle) === 1;
|
|
}
|
|
|
|
toString() {
|
|
return takeString(exports.temporalz_duration_to_string(this._handle));
|
|
}
|
|
|
|
toJSON() {
|
|
return this.toString();
|
|
}
|
|
|
|
toLocaleString() {
|
|
return this.toString();
|
|
}
|
|
|
|
valueOf() {
|
|
throw new TypeError("Cannot convert Temporal.Duration to a number");
|
|
}
|
|
|
|
get years() {
|
|
return Number(exports.temporalz_duration_years(this._handle));
|
|
}
|
|
|
|
get months() {
|
|
return Number(exports.temporalz_duration_months(this._handle));
|
|
}
|
|
|
|
get weeks() {
|
|
return Number(exports.temporalz_duration_weeks(this._handle));
|
|
}
|
|
|
|
get days() {
|
|
return Number(exports.temporalz_duration_days(this._handle));
|
|
}
|
|
|
|
get hours() {
|
|
return Number(exports.temporalz_duration_hours(this._handle));
|
|
}
|
|
|
|
get minutes() {
|
|
return Number(exports.temporalz_duration_minutes(this._handle));
|
|
}
|
|
|
|
get seconds() {
|
|
return Number(exports.temporalz_duration_seconds(this._handle));
|
|
}
|
|
|
|
get milliseconds() {
|
|
return Number(exports.temporalz_duration_milliseconds(this._handle));
|
|
}
|
|
|
|
get microseconds() {
|
|
return Number(exports.temporalz_duration_microseconds(this._handle));
|
|
}
|
|
|
|
get nanoseconds() {
|
|
return Number(exports.temporalz_duration_nanoseconds(this._handle));
|
|
}
|
|
}
|
|
|
|
function hasCalendarUnits(duration) {
|
|
return (
|
|
duration.years !== 0 ||
|
|
duration.months !== 0 ||
|
|
duration.weeks !== 0 ||
|
|
duration.days !== 0
|
|
);
|
|
}
|
|
|
|
function hasYearMonthWeek(duration) {
|
|
return duration.years !== 0 || duration.months !== 0 || duration.weeks !== 0;
|
|
}
|
|
|
|
function toRelativeTo(options) {
|
|
if (!options || options.relativeTo === undefined) return null;
|
|
const rel = options.relativeTo;
|
|
if (rel instanceof PlainDate) return rel;
|
|
if (typeof rel === "string") return PlainDate.from(rel);
|
|
if (rel && typeof rel === "object") return PlainDate.from(rel);
|
|
throw new TypeError("Invalid relativeTo");
|
|
}
|
|
|
|
const Temporal = {
|
|
Instant,
|
|
Duration,
|
|
Now: {
|
|
instant: unimplemented("Temporal.Now.instant"),
|
|
plainDateISO: unimplemented("Temporal.Now.plainDateISO"),
|
|
plainDateTimeISO: unimplemented("Temporal.Now.plainDateTimeISO"),
|
|
plainTimeISO: unimplemented("Temporal.Now.plainTimeISO"),
|
|
timeZoneId: unimplemented("Temporal.Now.timeZoneId"),
|
|
zonedDateTimeISO: unimplemented("Temporal.Now.zonedDateTimeISO"),
|
|
},
|
|
PlainDate,
|
|
PlainTime: unimplemented("Temporal.PlainTime"),
|
|
PlainDateTime: unimplemented("Temporal.PlainDateTime"),
|
|
PlainYearMonth: unimplemented("Temporal.PlainYearMonth"),
|
|
PlainMonthDay: unimplemented("Temporal.PlainMonthDay"),
|
|
ZonedDateTime: unimplemented("Temporal.ZonedDateTime"),
|
|
};
|
|
|
|
globalThis.Temporal = Temporal;
|
|
})();
|