Skip to content

Commit 73a0bf3

Browse files
authored
Implements globalThis slots (#175)
1 parent c0f7349 commit 73a0bf3

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

lib/slots.ts

+31-7
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,30 @@ interface SlotsToTypes {
150150

151151
type SlotKey = keyof SlotsToTypes;
152152

153-
const slots = new WeakMap();
154-
export function CreateSlots(container: AnyTemporalType): void {
155-
slots.set(container, Object.create(null));
153+
const globalSlots = new WeakMap<Slots[keyof Slots]['usedBy'], Record<keyof Slots, Slots[keyof Slots]['value']>>();
154+
155+
function _GetSlots(container: Slots[keyof Slots]['usedBy']) {
156+
return globalSlots.get(container);
156157
}
157158

158-
function GetSlots<T extends AnyTemporalType>(container: T) {
159-
return slots.get(container);
159+
const GetSlotsSymbol = Symbol.for('@@Temporal__GetSlots');
160+
161+
// expose GetSlots to avoid dual package hazards
162+
(globalThis as any)[GetSlotsSymbol] ||= _GetSlots;
163+
164+
const GetSlots = (globalThis as any)[GetSlotsSymbol] as typeof _GetSlots;
165+
166+
function _CreateSlots(container: Slots[keyof Slots]['usedBy']): void {
167+
globalSlots.set(container, Object.create(null));
160168
}
169+
170+
const CreateSlotsSymbol = Symbol.for('@@Temporal__CreateSlots');
171+
172+
// expose CreateSlots to avoid dual package hazards
173+
(globalThis as any)[CreateSlotsSymbol] ||= _CreateSlots;
174+
175+
export const CreateSlots = (globalThis as any)[CreateSlotsSymbol] as typeof _CreateSlots;
176+
161177
// TODO: is there a better way than 9 overloads to make HasSlot into a type
162178
// guard that takes a variable number of parameters?
163179
export function HasSlot<ID1 extends SlotKey>(container: unknown, id1: ID1): container is Slots[ID1]['usedBy'];
@@ -278,7 +294,7 @@ export function GetSlot<KeyT extends keyof Slots>(
278294
container: Slots[typeof id]['usedBy'],
279295
id: KeyT
280296
): Slots[KeyT]['value'] {
281-
const value = GetSlots(container)[id];
297+
const value = GetSlots(container)?.[id];
282298
if (value === undefined) throw new TypeError(`Missing internal slot ${id}`);
283299
return value;
284300
}
@@ -287,5 +303,13 @@ export function SetSlot<KeyT extends SlotKey>(
287303
id: KeyT,
288304
value: Slots[KeyT]['value']
289305
): void {
290-
GetSlots(container)[id] = value;
306+
const slots = GetSlots(container);
307+
308+
if (slots === undefined) throw new TypeError('Missing slots for the given container');
309+
310+
const existingSlot = slots[id];
311+
312+
if (existingSlot) throw new TypeError(`${id} already has set`);
313+
314+
slots[id] = value;
291315
}

test/test262.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22
# Note that this script is only expected to be run via `npm run test262`, not by
33
# being manually executed.
44
set -e

0 commit comments

Comments
 (0)