Skip to content

Commit fd05b91

Browse files
committed
defineGlobally can be reverted
1 parent 49102e8 commit fd05b91

4 files changed

Lines changed: 85 additions & 24 deletions

File tree

src/polytype-esm.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,20 @@ const createUnionProxy =
460460
};
461461

462462
const defineGlobally =
463-
() =>
463+
undo =>
464464
{
465-
if (globalThis.hasOwnProperty('classes'))
465+
if (globalThis.hasOwnProperty('classes') === !undo)
466466
return false;
467-
defineMutableDataProperty(globalThis, 'classes', classes);
468-
defineMutableDataProperty(_Object, 'getPrototypeListOf', getPrototypeListOf);
467+
if (undo)
468+
{
469+
delete globalThis.classes;
470+
delete _Object.getPrototypeListOf;
471+
}
472+
else
473+
{
474+
defineMutableDataProperty(globalThis, 'classes', classes);
475+
defineMutableDataProperty(_Object, 'getPrototypeListOf', getPrototypeListOf);
476+
}
469477
return true;
470478
};
471479

src/polytype.d.ts.hbs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,28 @@ Polytype.ClusteredConstructor<T>;
129129
{{> classes q="export function "}}
130130

131131
/**
132-
* Globally defines `classes` and `Object.getPrototypeListOf`.
132+
* Globally defines or undefines `classes` and `Object.getPrototypeListOf`.
133133
*
134-
* Calling this function allows using Polytype everywhere inside the current JavaScript realm
135-
* without imports.
134+
* Calling this function without arguments or with a falsy argument allows using Polytype everywhere
135+
* inside the current JavaScript realm without imports.
136+
* Calling it again with a truthy argument reverts the changes made by the previous call.
136137
*
137138
* This function is only available in the module versions of Polytype.
138139
* For most purposes it is better to import the global version of Polytype directly rather than
139140
* calling this function.
140141
*
142+
* @param undo
143+
*
144+
* If this argument is falsy or unspecified, `classes` and `Object.getPrototypeListOf` will be
145+
* defined globally.
146+
* If this argument is truthy, the globals `classes` and `Object.getPrototypeListOf` will be
147+
* deleted.
148+
*
141149
* @returns
142150
*
143-
* `true` on success; `false` otherwise.
151+
* `true` if any changes were made; `false` otherwise.
144152
*/
145-
export function defineGlobally(): boolean;
153+
export function defineGlobally(uninstall?: boolean): boolean;
146154

147155
{{> getPrototypeListOf q="export function "}}
148156
{{else}}

test/spec-helper.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,22 @@
77
{
88
function backupGlobals()
99
{
10-
const globalThisDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'globalThis');
10+
const _globalThis = globalThis;
1111

1212
let bindDescriptor;
1313
let classesDescriptor;
1414
let fnHasInstanceDescriptor;
1515
let getPrototypeListOfDescriptor;
16+
let globalThisDescriptor;
1617
let isPrototypeOfDescriptor;
1718
let objHasInstanceDescriptor;
1819

1920
before
2021
(
2122
() =>
2223
{
23-
classesDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'classes');
24+
classesDescriptor = Object.getOwnPropertyDescriptor(_globalThis, 'classes');
25+
globalThisDescriptor = Object.getOwnPropertyDescriptor(_globalThis, 'globalThis');
2426
fnHasInstanceDescriptor =
2527
Object.getOwnPropertyDescriptor(Function, Symbol.hasInstance);
2628
bindDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'bind');
@@ -37,8 +39,8 @@
3739
(
3840
() =>
3941
{
40-
setPropertyDescriptor(globalThis, 'globalThis', globalThisDescriptor);
41-
Object.defineProperty(globalThis, 'classes', classesDescriptor);
42+
Object.defineProperty(_globalThis, 'classes', classesDescriptor);
43+
Object.defineProperty(_globalThis, 'globalThis', globalThisDescriptor);
4244
setPropertyDescriptor(Function, Symbol.hasInstance, fnHasInstanceDescriptor);
4345
// eslint-disable-next-line no-extend-native
4446
Object.defineProperty(Function.prototype, 'bind', bindDescriptor);

test/spec/common/define-globally.spec.js

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,69 @@ maybeDescribe
99
'defineGlobally',
1010
() =>
1111
{
12+
let defineGlobally;
13+
14+
before
15+
(async () => { defineGlobally = await loadPolytype(); });
16+
17+
after
18+
(() => { defineGlobally = null; });
19+
1220
backupGlobals();
1321

14-
it
22+
describe
1523
(
16-
'returns true',
17-
async () =>
24+
'with a falsy argument',
25+
() =>
1826
{
19-
const defineGlobally = await loadPolytype();
20-
delete globalThis.classes;
21-
assert.strictEqual(defineGlobally(), true);
27+
it
28+
(
29+
'returns true',
30+
() =>
31+
{
32+
delete globalThis.classes;
33+
assert.strictEqual(defineGlobally(), true);
34+
assert.isFunction(globalThis.classes);
35+
assert.isFunction(Object.getPrototypeListOf);
36+
},
37+
);
38+
39+
it
40+
(
41+
'returns false',
42+
() =>
43+
{
44+
assert.strictEqual(defineGlobally(), false);
45+
},
46+
);
2247
},
2348
);
2449

25-
it
50+
describe
2651
(
27-
'returns false',
28-
async () =>
52+
'with a truthy argument',
53+
() =>
2954
{
30-
const defineGlobally = await loadPolytype();
31-
assert.strictEqual(defineGlobally(), false);
55+
it
56+
(
57+
'returns true',
58+
() =>
59+
{
60+
assert.strictEqual(defineGlobally(true), true);
61+
assert.isNotFunction(globalThis.classes);
62+
assert.isNotFunction(Object.getPrototypeListOf);
63+
},
64+
);
65+
66+
it
67+
(
68+
'returns false',
69+
() =>
70+
{
71+
delete globalThis.classes;
72+
assert.strictEqual(defineGlobally(true), false);
73+
},
74+
);
3275
},
3376
);
3477
},

0 commit comments

Comments
 (0)