- Add GETTING_STARTED.md with quick start guide and development modes - Add INSTALL.sh automated installation script - Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md - Add QUICK_REFERENCE.md for common commands - Add SETUP_GUIDE.md with detailed setup instructions - Update README.md with improved project overview - Add did-wallet app dependencies and node_modules
316 lines
9.3 KiB
TypeScript
316 lines
9.3 KiB
TypeScript
import type JSBI from 'jsbi';
|
|
import type { Temporal } from '..';
|
|
import type { BuiltinCalendarId, AnyTemporalType, CalendarSlot, TimeZoneSlot } from './internaltypes';
|
|
|
|
// Instant
|
|
export const EPOCHNANOSECONDS = 'slot-epochNanoSeconds';
|
|
|
|
// TimeZone
|
|
export const TIMEZONE_ID = 'slot-timezone-identifier';
|
|
|
|
// DateTime, Date, Time, YearMonth, MonthDay
|
|
export const ISO_YEAR = 'slot-year';
|
|
export const ISO_MONTH = 'slot-month';
|
|
export const ISO_DAY = 'slot-day';
|
|
export const ISO_HOUR = 'slot-hour';
|
|
export const ISO_MINUTE = 'slot-minute';
|
|
export const ISO_SECOND = 'slot-second';
|
|
export const ISO_MILLISECOND = 'slot-millisecond';
|
|
export const ISO_MICROSECOND = 'slot-microsecond';
|
|
export const ISO_NANOSECOND = 'slot-nanosecond';
|
|
export const CALENDAR = 'slot-calendar';
|
|
// Date, YearMonth, and MonthDay all have the same slots, disambiguation needed:
|
|
export const DATE_BRAND = 'slot-date-brand';
|
|
export const YEAR_MONTH_BRAND = 'slot-year-month-brand';
|
|
export const MONTH_DAY_BRAND = 'slot-month-day-brand';
|
|
|
|
// ZonedDateTime
|
|
export const INSTANT = 'slot-cached-instant';
|
|
export const TIME_ZONE = 'slot-time-zone';
|
|
|
|
// Duration
|
|
export const YEARS = 'slot-years';
|
|
export const MONTHS = 'slot-months';
|
|
export const WEEKS = 'slot-weeks';
|
|
export const DAYS = 'slot-days';
|
|
export const HOURS = 'slot-hours';
|
|
export const MINUTES = 'slot-minutes';
|
|
export const SECONDS = 'slot-seconds';
|
|
export const MILLISECONDS = 'slot-milliseconds';
|
|
export const MICROSECONDS = 'slot-microseconds';
|
|
export const NANOSECONDS = 'slot-nanoseconds';
|
|
|
|
// Calendar
|
|
export const CALENDAR_ID = 'slot-calendar-identifier';
|
|
|
|
interface SlotInfo<ValueType, UsedByType extends AnyTemporalType> {
|
|
value: ValueType;
|
|
usedBy: UsedByType;
|
|
}
|
|
|
|
interface SlotInfoRecord {
|
|
[k: string]: SlotInfo<unknown, AnyTemporalType>;
|
|
}
|
|
|
|
interface Slots extends SlotInfoRecord {
|
|
// Instant
|
|
[EPOCHNANOSECONDS]: SlotInfo<JSBI, Temporal.Instant | Temporal.ZonedDateTime>; // number? JSBI?
|
|
|
|
// TimeZone
|
|
[TIMEZONE_ID]: SlotInfo<string, Temporal.TimeZone>;
|
|
|
|
// DateTime, Date, Time, YearMonth, MonthDay
|
|
[ISO_YEAR]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_MONTH]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_DAY]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_HOUR]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_MINUTE]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_SECOND]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_MILLISECOND]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_MICROSECOND]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[ISO_NANOSECOND]: SlotInfo<number, TypesWithCalendarUnits>;
|
|
[CALENDAR]: SlotInfo<CalendarSlot, TypesWithCalendarUnits>;
|
|
|
|
// Date, YearMonth, MonthDay common slots
|
|
[DATE_BRAND]: SlotInfo<true, Temporal.PlainDate>;
|
|
[YEAR_MONTH_BRAND]: SlotInfo<true, Temporal.PlainYearMonth>;
|
|
[MONTH_DAY_BRAND]: SlotInfo<true, Temporal.PlainMonthDay>;
|
|
|
|
// ZonedDateTime
|
|
[INSTANT]: SlotInfo<Temporal.Instant, Temporal.ZonedDateTime>;
|
|
[TIME_ZONE]: SlotInfo<TimeZoneSlot, Temporal.ZonedDateTime>;
|
|
|
|
// Duration
|
|
[YEARS]: SlotInfo<number, Temporal.Duration>;
|
|
[MONTHS]: SlotInfo<number, Temporal.Duration>;
|
|
[WEEKS]: SlotInfo<number, Temporal.Duration>;
|
|
[DAYS]: SlotInfo<number, Temporal.Duration>;
|
|
[HOURS]: SlotInfo<number, Temporal.Duration>;
|
|
[MINUTES]: SlotInfo<number, Temporal.Duration>;
|
|
[SECONDS]: SlotInfo<number, Temporal.Duration>;
|
|
[MILLISECONDS]: SlotInfo<number, Temporal.Duration>;
|
|
[MICROSECONDS]: SlotInfo<number, Temporal.Duration>;
|
|
[NANOSECONDS]: SlotInfo<number, Temporal.Duration>;
|
|
|
|
// Calendar
|
|
[CALENDAR_ID]: SlotInfo<BuiltinCalendarId, Temporal.Calendar>;
|
|
}
|
|
|
|
type TypesWithCalendarUnits =
|
|
| Temporal.PlainDateTime
|
|
| Temporal.PlainDate
|
|
| Temporal.PlainTime
|
|
| Temporal.PlainYearMonth
|
|
| Temporal.PlainMonthDay
|
|
| Temporal.ZonedDateTime;
|
|
|
|
interface SlotsToTypes {
|
|
// Instant
|
|
[EPOCHNANOSECONDS]: Temporal.Instant;
|
|
|
|
// TimeZone
|
|
[TIMEZONE_ID]: Temporal.TimeZone;
|
|
|
|
// DateTime, Date, Time, YearMonth, MonthDay
|
|
[ISO_YEAR]: TypesWithCalendarUnits;
|
|
[ISO_MONTH]: TypesWithCalendarUnits;
|
|
[ISO_DAY]: TypesWithCalendarUnits;
|
|
[ISO_HOUR]: TypesWithCalendarUnits;
|
|
[ISO_MINUTE]: TypesWithCalendarUnits;
|
|
[ISO_SECOND]: TypesWithCalendarUnits;
|
|
[ISO_MILLISECOND]: TypesWithCalendarUnits;
|
|
[ISO_MICROSECOND]: TypesWithCalendarUnits;
|
|
[ISO_NANOSECOND]: TypesWithCalendarUnits;
|
|
[CALENDAR]: TypesWithCalendarUnits;
|
|
|
|
// Date, YearMonth, MonthDay common slots
|
|
[DATE_BRAND]: Temporal.PlainDate;
|
|
[YEAR_MONTH_BRAND]: Temporal.PlainYearMonth;
|
|
[MONTH_DAY_BRAND]: Temporal.PlainMonthDay;
|
|
|
|
// ZonedDateTime
|
|
[INSTANT]: Temporal.ZonedDateTime;
|
|
[TIME_ZONE]: Temporal.ZonedDateTime;
|
|
|
|
// Duration
|
|
[YEARS]: Temporal.Duration;
|
|
[MONTHS]: Temporal.Duration;
|
|
[WEEKS]: Temporal.Duration;
|
|
[DAYS]: Temporal.Duration;
|
|
[HOURS]: Temporal.Duration;
|
|
[MINUTES]: Temporal.Duration;
|
|
[SECONDS]: Temporal.Duration;
|
|
[MILLISECONDS]: Temporal.Duration;
|
|
[MICROSECONDS]: Temporal.Duration;
|
|
[NANOSECONDS]: Temporal.Duration;
|
|
|
|
// Calendar
|
|
[CALENDAR_ID]: Temporal.Calendar;
|
|
}
|
|
|
|
type SlotKey = keyof SlotsToTypes;
|
|
|
|
const globalSlots = new WeakMap<Slots[keyof Slots]['usedBy'], Record<keyof Slots, Slots[keyof Slots]['value']>>();
|
|
|
|
function _GetSlots(container: Slots[keyof Slots]['usedBy']) {
|
|
return globalSlots.get(container);
|
|
}
|
|
|
|
const GetSlotsSymbol = Symbol.for('@@Temporal__GetSlots');
|
|
|
|
// expose GetSlots to avoid dual package hazards
|
|
(globalThis as any)[GetSlotsSymbol] ||= _GetSlots;
|
|
|
|
const GetSlots = (globalThis as any)[GetSlotsSymbol] as typeof _GetSlots;
|
|
|
|
function _CreateSlots(container: Slots[keyof Slots]['usedBy']): void {
|
|
globalSlots.set(container, Object.create(null));
|
|
}
|
|
|
|
const CreateSlotsSymbol = Symbol.for('@@Temporal__CreateSlots');
|
|
|
|
// expose CreateSlots to avoid dual package hazards
|
|
(globalThis as any)[CreateSlotsSymbol] ||= _CreateSlots;
|
|
|
|
export const CreateSlots = (globalThis as any)[CreateSlotsSymbol] as typeof _CreateSlots;
|
|
|
|
// TODO: is there a better way than 9 overloads to make HasSlot into a type
|
|
// guard that takes a variable number of parameters?
|
|
export function HasSlot<ID1 extends SlotKey>(container: unknown, id1: ID1): container is Slots[ID1]['usedBy'];
|
|
export function HasSlot<ID1 extends SlotKey, ID2 extends SlotKey>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2
|
|
): container is Slots[ID1]['usedBy'] | Slots[ID2]['usedBy'];
|
|
export function HasSlot<ID1 extends SlotKey, ID2 extends SlotKey, ID3 extends SlotKey>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3
|
|
): container is Slots[ID1]['usedBy'] | Slots[ID2]['usedBy'] | Slots[ID3]['usedBy'];
|
|
export function HasSlot<ID1 extends SlotKey, ID2 extends SlotKey, ID3 extends SlotKey, ID4 extends SlotKey>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3,
|
|
id4: ID4
|
|
): container is Slots[ID1 | ID2 | ID3 | ID4]['usedBy'];
|
|
export function HasSlot<
|
|
ID1 extends SlotKey,
|
|
ID2 extends SlotKey,
|
|
ID3 extends SlotKey,
|
|
ID4 extends SlotKey,
|
|
ID5 extends SlotKey
|
|
>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3,
|
|
id4: ID4,
|
|
id5: ID5
|
|
): container is Slots[ID1 | ID2 | ID3 | ID4 | ID5]['usedBy'];
|
|
export function HasSlot<
|
|
ID1 extends SlotKey,
|
|
ID2 extends SlotKey,
|
|
ID3 extends SlotKey,
|
|
ID4 extends SlotKey,
|
|
ID5 extends SlotKey,
|
|
ID6 extends SlotKey
|
|
>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3,
|
|
id4: ID4,
|
|
id5: ID5,
|
|
id6: ID6
|
|
): container is Slots[ID1 | ID2 | ID3 | ID4 | ID5 | ID6]['usedBy'];
|
|
export function HasSlot<
|
|
ID1 extends SlotKey,
|
|
ID2 extends SlotKey,
|
|
ID3 extends SlotKey,
|
|
ID4 extends SlotKey,
|
|
ID5 extends SlotKey,
|
|
ID6 extends SlotKey,
|
|
ID7 extends SlotKey
|
|
>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3,
|
|
id4: ID4,
|
|
id5: ID5,
|
|
id6: ID6,
|
|
id7: ID7
|
|
): container is Slots[ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7]['usedBy'];
|
|
export function HasSlot<
|
|
ID1 extends SlotKey,
|
|
ID2 extends SlotKey,
|
|
ID3 extends SlotKey,
|
|
ID4 extends SlotKey,
|
|
ID5 extends SlotKey,
|
|
ID6 extends SlotKey,
|
|
ID7 extends SlotKey,
|
|
ID8 extends SlotKey
|
|
>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3,
|
|
id4: ID4,
|
|
id5: ID5,
|
|
id6: ID6,
|
|
id7: ID7,
|
|
id8: ID8
|
|
): container is Slots[ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | ID8]['usedBy'];
|
|
export function HasSlot<
|
|
ID1 extends SlotKey,
|
|
ID2 extends SlotKey,
|
|
ID3 extends SlotKey,
|
|
ID4 extends SlotKey,
|
|
ID5 extends SlotKey,
|
|
ID6 extends SlotKey,
|
|
ID7 extends SlotKey,
|
|
ID8 extends SlotKey,
|
|
ID9 extends SlotKey
|
|
>(
|
|
container: unknown,
|
|
id1: ID1,
|
|
id2: ID2,
|
|
id3: ID3,
|
|
id4: ID4,
|
|
id5: ID5,
|
|
id6: ID6,
|
|
id7: ID7,
|
|
id8: ID8,
|
|
id9: ID9
|
|
): container is Slots[ID1 | ID2 | ID3 | ID4 | ID5 | ID6 | ID7 | ID8 | ID9]['usedBy'];
|
|
export function HasSlot(container: unknown, ...ids: (keyof Slots)[]): boolean {
|
|
if (!container || 'object' !== typeof container) return false;
|
|
const myslots = GetSlots(container as AnyTemporalType);
|
|
return !!myslots && ids.every((id) => id in myslots);
|
|
}
|
|
export function GetSlot<KeyT extends keyof Slots>(
|
|
container: Slots[typeof id]['usedBy'],
|
|
id: KeyT
|
|
): Slots[KeyT]['value'] {
|
|
const value = GetSlots(container)?.[id];
|
|
if (value === undefined) throw new TypeError(`Missing internal slot ${id}`);
|
|
return value;
|
|
}
|
|
export function SetSlot<KeyT extends SlotKey>(
|
|
container: Slots[KeyT]['usedBy'],
|
|
id: KeyT,
|
|
value: Slots[KeyT]['value']
|
|
): void {
|
|
const slots = GetSlots(container);
|
|
|
|
if (slots === undefined) throw new TypeError('Missing slots for the given container');
|
|
|
|
const existingSlot = slots[id];
|
|
|
|
if (existingSlot) throw new TypeError(`${id} already has set`);
|
|
|
|
slots[id] = value;
|
|
}
|