disposablestack
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -8,2 +8,14 @@ # Changelog | ||
## [v1.1.0](https://github.com/es-shims/DisposableStack/compare/v1.0.0...v1.1.0) - 2023-04-12 | ||
### Commits | ||
- [New] add `AsyncDisposableStack` [`7f20fa1`](https://github.com/es-shims/DisposableStack/commit/7f20fa1d289520ee90fd347241c9ab7862e96095) | ||
- [New] add `Symbol.asyncDispose` [`cf0d13c`](https://github.com/es-shims/DisposableStack/commit/cf0d13ca7e52a54179e74071abc03a9e2225f993) | ||
- [Tests] simple cleanup [`1be651d`](https://github.com/es-shims/DisposableStack/commit/1be651d8a447b16623fa8833432d805cc55d3b13) | ||
- [Refactor] clean up per https://github.com/tc39/proposal-explicit-resource-management/pull/150 [`e7dbbd8`](https://github.com/es-shims/DisposableStack/commit/e7dbbd87b4c6c2531c20a62a2eb16a0bb5163179) | ||
- [Refactor] move AOs higher up [`9ff6444`](https://github.com/es-shims/DisposableStack/commit/9ff644488a1f939f9250163ae31ad2565bae7141) | ||
- [patch] improve error messages [`f7c572c`](https://github.com/es-shims/DisposableStack/commit/f7c572c7604efe5d64a248ef8142a7ca6ea5570e) | ||
- [Deps] update `es-abstract` [`ecbc99e`](https://github.com/es-shims/DisposableStack/commit/ecbc99e063adaa58b77b36395fd29aeb996cbf8a) | ||
## v1.0.0 - 2023-02-17 | ||
@@ -10,0 +22,0 @@ |
@@ -21,5 +21,5 @@ 'use strict'; | ||
var AddDisposableResource = require('./aos/AddDisposableResource'); | ||
var DisposeResources = require('./aos/DisposeResources'); | ||
var NewDisposeCapability = require('./aos/NewDisposeCapability'); | ||
var AddDisposableResource = require('../aos/AddDisposableResource'); | ||
var DisposeResources = require('../aos/DisposeResources'); | ||
var NewDisposeCapability = require('../aos/NewDisposeCapability'); | ||
@@ -26,0 +26,0 @@ var symbolDispose = require('../Symbol.dispose/polyfill')(); |
[ | ||
"Symbol.dispose", | ||
"Symbol.asyncDispose", | ||
"DisposableStack", | ||
"Symbol.dispose" | ||
"AsyncDisposableStack" | ||
] |
{ | ||
"name": "disposablestack", | ||
"version": "1.0.0", | ||
"description": "An ESnext spec-compliant `DisposableStack` and `Symbol.dispose` shim/polyfill/replacement that works as far down as ES3.", | ||
"version": "1.1.0", | ||
"description": "An ESnext spec-compliant `DisposableStack`, `AsyncDisposableStack`, `Symbol.dispose`, and `Symbol.asyncDispose` shim/polyfill/replacement that works as far down as ES3.", | ||
"main": "index.json", | ||
@@ -15,2 +15,7 @@ "exports": { | ||
"./DisposableStack/shim": "./DisposableStack/shim.js", | ||
"./AsyncDisposableStack": "./AsyncDisposableStack/index.js", | ||
"./AsyncDisposableStack/auto": "./AsyncDisposableStack/auto.js", | ||
"./AsyncDisposableStack/polyfill": "./AsyncDisposableStack/polyfill.js", | ||
"./AsyncDisposableStack/implementation": "./AsyncDisposableStack/implementation.js", | ||
"./AsyncDisposableStack/shim": "./AsyncDisposableStack/shim.js", | ||
"./Symbol.dispose": "./Symbol.dispose/index.js", | ||
@@ -21,2 +26,7 @@ "./Symbol.dispose/auto": "./Symbol.dispose/auto.js", | ||
"./Symbol.dispose/shim": "./Symbol.dispose/shim.js", | ||
"./Symbol.asyncDispose": "./Symbol.asyncDispose/index.js", | ||
"./Symbol.asyncDispose/auto": "./Symbol.asyncDispose/auto.js", | ||
"./Symbol.asyncDispose/polyfill": "./Symbol.asyncDispose/polyfill.js", | ||
"./Symbol.asyncDispose/implementation": "./Symbol.asyncDispose/implementation.js", | ||
"./Symbol.asyncDispose/shim": "./Symbol.asyncDispose/shim.js", | ||
"./package.json": "./package.json" | ||
@@ -45,6 +55,11 @@ }, | ||
"DisposableStack", | ||
"AsyncDisposableStack", | ||
"dispose", | ||
"asyncDispose", | ||
"using", | ||
"resource", | ||
"management" | ||
"management", | ||
"Symbol", | ||
"Symbol.dispose", | ||
"Symbol.asyncDispose" | ||
], | ||
@@ -59,3 +74,3 @@ "author": "Jordan Harband <ljharb@gmail.com>", | ||
"define-properties": "^1.2.0", | ||
"es-abstract": "^1.21.1", | ||
"es-abstract": "^1.21.2", | ||
"es-set-tostringtag": "^2.0.1", | ||
@@ -62,0 +77,0 @@ "get-intrinsic": "^1.2.0", |
@@ -12,8 +12,6 @@ # disposablestack <sup>[![Version Badge][npm-version-svg]][package-url]</sup> | ||
An ESnext spec-compliant `DisposableStack` and `Symbol.dispose` shim/polyfill/replacement that works as far down as ES3. | ||
An ESnext spec-compliant `DisposableStack`, `AsyncDisposableStack`, `Symbol.dispose`, and `Symbol.asyncDispose` shim/polyfill/replacement that works as far down as ES3. | ||
Its root `auto` entrypoint also provides `SuppressedError`, via the [`suppressed-error`](https://npmjs.com/suppressed-error) package. | ||
In the future, this package will also provide `AsyncDisposableStack` and `Symbol.asyncDispose`, or whichever forms end up in stage 3. | ||
This package implements the [es-shim API](https://github.com/es-shims/api) “multi” interface. It works in an ES3-supported environment and complies with the proposed [spec](https://tc39.es/proposal-explicit-resource-management/). | ||
@@ -35,2 +33,3 @@ | ||
assert.equal(typeof Symbol.dispose, 'symbol'); | ||
assert.equal(typeof Symbol.asyncDispose, 'symbol'); | ||
@@ -42,2 +41,4 @@ const error = new SuppressedError(); | ||
const asyncStack = new AsyncDisposableStack(); | ||
// examples of stack methods | ||
@@ -47,2 +48,4 @@ | ||
asyncStack.dispose(); | ||
// assert disposal was done | ||
@@ -49,0 +52,0 @@ ``` |
'use strict'; | ||
var shimSymbolDispose = require('./Symbol.dispose/shim'); | ||
var shimSymbolAsyncDispose = require('./Symbol.asyncDispose/shim'); | ||
var shimDisposableStack = require('./DisposableStack/shim'); | ||
var shimSymbolDispose = require('./Symbol.dispose/shim'); | ||
var shimAsyncDisposableStack = require('./AsyncDisposableStack/shim'); | ||
module.exports = function shim() { | ||
shimSymbolDispose(); | ||
shimSymbolAsyncDispose(); | ||
shimDisposableStack(); | ||
shimSymbolDispose(); | ||
shimAsyncDisposableStack(); | ||
}; |
@@ -6,17 +6,23 @@ 'use strict'; | ||
var symbolDispose = require('../Symbol.dispose/implementation'); | ||
var symbolAsyncDispose = require('../Symbol.asyncDispose/implementation'); | ||
var DisposableStack = require('../DisposableStack/implementation'); | ||
var AsyncDisposableStack = require('../AsyncDisposableStack/implementation'); | ||
var shims = require('../'); | ||
var runTests = require('./tests'); | ||
test('shims', function (t) { | ||
t.deepEqual(shims, ['DisposableStack', 'Symbol.dispose'], 'has expected shims'); | ||
/* eslint new-cap: 0 */ | ||
t.end(); | ||
}); | ||
test('implementation', function (t) { | ||
test('Symbol.dispose', function (st) { | ||
runTests['Symbol.dispose'](st, symbolDispose); | ||
/* eslint new-cap: 0 */ | ||
st.end(); | ||
}); | ||
test('implementation', function (t) { | ||
test('Symbol.asyncDispose', function (st) { | ||
runTests['Symbol.asyncDispose'](st, symbolAsyncDispose); | ||
st.end(); | ||
}); | ||
test('DisposableStack', function (st) { | ||
@@ -28,4 +34,4 @@ runTests.DisposableStack(st, DisposableStack, symbolDispose); | ||
test('Symbol.dispose', function (st) { | ||
runTests['Symbol.dispose'](st, symbolDispose); | ||
test('AsyncDisposableStack', function (st) { | ||
runTests.AsyncDisposableStack(st, AsyncDisposableStack, symbolAsyncDispose); | ||
@@ -32,0 +38,0 @@ st.end(); |
@@ -6,3 +6,5 @@ 'use strict'; | ||
var symbolDispose = require('../Symbol.dispose'); | ||
var symbolAsyncDispose = require('../Symbol.asyncDispose'); | ||
var DisposableStack = require('../DisposableStack'); | ||
var AsyncDisposableStack = require('../AsyncDisposableStack'); | ||
@@ -14,3 +16,3 @@ var shims = require('../'); | ||
test('shims', function (t) { | ||
t.deepEqual(shims, ['DisposableStack', 'Symbol.dispose'], 'has expected shims'); | ||
t.deepEqual(shims, ['Symbol.dispose', 'Symbol.asyncDispose', 'DisposableStack', 'AsyncDisposableStack'], 'has expected shims'); | ||
@@ -23,2 +25,14 @@ t.end(); | ||
test('index', function (t) { | ||
test('Symbol.dispose', function (st) { | ||
runTests['Symbol.dispose'](st, symbolDispose); | ||
st.end(); | ||
}); | ||
test('Symbol.asyncDispose', function (st) { | ||
runTests['Symbol.asyncDispose'](st, symbolAsyncDispose); | ||
st.end(); | ||
}); | ||
test('DisposableStack', function (st) { | ||
@@ -30,4 +44,4 @@ runTests.DisposableStack(st, DisposableStack, symbolDispose); | ||
test('Symbol.dispose', function (st) { | ||
runTests['Symbol.dispose'](st, symbolDispose); | ||
test('AsyncDisposableStack', function (st) { | ||
runTests.AsyncDisposableStack(st, AsyncDisposableStack, symbolAsyncDispose); | ||
@@ -34,0 +48,0 @@ st.end(); |
@@ -8,4 +8,2 @@ 'use strict'; | ||
var shims = require('../'); | ||
var runTests = require('./tests'); | ||
@@ -15,11 +13,41 @@ | ||
test('shims', function (t) { | ||
t.deepEqual(shims, ['DisposableStack', 'Symbol.dispose'], 'has expected shims'); | ||
/* eslint new-cap: 0 */ | ||
t.end(); | ||
}); | ||
test('shimmed', function (t) { | ||
test('Symbol.dispose', { skip: !hasSymbols }, function (st) { | ||
if (hasPropertyDescriptors) { | ||
st.deepEqual( | ||
Object.getOwnPropertyDescriptor(Symbol, 'dispose'), | ||
{ | ||
configurable: false, | ||
enumerable: false, | ||
value: Symbol.dispose, | ||
writable: false | ||
} | ||
); | ||
} | ||
/* eslint new-cap: 0 */ | ||
runTests['Symbol.dispose'](st, Symbol.dispose); | ||
test('index', function (t) { | ||
st.end(); | ||
}); | ||
test('Symbol.asyncDispose', { skip: !hasSymbols }, function (st) { | ||
if (hasPropertyDescriptors) { | ||
st.deepEqual( | ||
Object.getOwnPropertyDescriptor(Symbol, 'asyncDispose'), | ||
{ | ||
configurable: false, | ||
enumerable: false, | ||
value: Symbol.asyncDispose, | ||
writable: false | ||
} | ||
); | ||
} | ||
runTests['Symbol.asyncDispose'](st, Symbol.asyncDispose); | ||
st.end(); | ||
}); | ||
test('DisposableStack', function (st) { | ||
@@ -43,11 +71,11 @@ if (hasPropertyDescriptors) { | ||
test('Symbol.dispose', { skip: !hasSymbols }, function (st) { | ||
test('AsyncDisposableStack', function (st) { | ||
if (hasPropertyDescriptors) { | ||
st.deepEqual( | ||
Object.getOwnPropertyDescriptor(Symbol, 'dispose'), | ||
Object.getOwnPropertyDescriptor(global, 'AsyncDisposableStack'), | ||
{ | ||
configurable: false, | ||
configurable: true, | ||
enumerable: false, | ||
value: Symbol.dispose, | ||
writable: false | ||
value: AsyncDisposableStack, | ||
writable: true | ||
} | ||
@@ -57,3 +85,3 @@ ); | ||
runTests['Symbol.dispose'](st, Symbol.dispose); | ||
runTests.AsyncDisposableStack(st, AsyncDisposableStack, hasSymbols ? Symbol.asyncDispose : null); | ||
@@ -60,0 +88,0 @@ st.end(); |
@@ -305,2 +305,296 @@ 'use strict'; | ||
}, | ||
AsyncDisposableStack: function testAsyncDisposableStack(t, AsyncDisposableStack, symbolAsyncDispose) { | ||
t.equal(typeof AsyncDisposableStack, 'function', 'is a function'); | ||
t.equal(typeof new AsyncDisposableStack(), 'object', 'returns an object'); | ||
t.ok(new AsyncDisposableStack() instanceof AsyncDisposableStack, 'returns an instance of AsyncDisposableStack'); | ||
t['throws']( | ||
function () { AsyncDisposableStack(); }, // eslint-disable-line new-cap | ||
TypeError, | ||
'throws a TypeError if not called with `new`' | ||
); | ||
var throwSentinel = { 'throws': true }; | ||
var throwsSentinel = function throwsSentinel() { | ||
throw throwSentinel; | ||
}; | ||
t.test('disposed', { skip: typeof Promise !== 'function' }, function (st) { | ||
var instance = new AsyncDisposableStack(); | ||
st.equal(instance.disposed, false, 'is not disposed'); | ||
st.test('has accessors', { skip: !supportsDescriptors }, function (s2t) { | ||
s2t.notOk(has(instance, 'disposed'), 'has no own `disposed` property'); | ||
var desc = Object.getOwnPropertyDescriptor(AsyncDisposableStack.prototype, 'disposed'); | ||
s2t.deepEqual( | ||
desc, | ||
{ | ||
configurable: true, | ||
enumerable: true, | ||
get: desc.get, | ||
set: undefined | ||
}, | ||
'has a prototype accessor' | ||
); | ||
s2t.equal(instance.disposed, desc.get.call(instance), 'instance Get matches prototype getter Call'); | ||
return Promise.resolve(instance.disposeAsync()).then(function () { | ||
s2t.equal(instance.disposed, desc.get.call(instance), 'instance Get still matches prototype getter Call'); | ||
s2t.equal(instance.disposed, true, 'is now disposed'); | ||
}); | ||
}); | ||
st.test('no accessors', { skip: supportsDescriptors }, function (s2t) { | ||
s2t.ok(has(instance, 'disposed'), 'has an own `disposed` property'); | ||
return instance.disposeAsync().then(function () { | ||
s2t.ok(has(instance, 'disposed'), 'still has an own `disposed` property'); | ||
s2t.equal(instance.disposed, true, 'is now disposed'); | ||
}); | ||
}); | ||
st.end(); | ||
}); | ||
t.test('use', { skip: !symbolAsyncDispose }, function (st) { | ||
var instance = new AsyncDisposableStack(); | ||
var count = 0; | ||
var disposable = {}; | ||
disposable[symbolAsyncDispose] = function () { | ||
count += 1; | ||
}; | ||
instance.use(disposable); | ||
instance.use(null); | ||
instance.use(); | ||
instance.use(disposable); | ||
forEach(v.nonNullPrimitives, function (nonNullishObject) { | ||
st['throws']( | ||
function () { instance.use(nonNullishObject); }, | ||
TypeError, | ||
'throws on a non-object: ' + inspect(nonNullishObject) | ||
); | ||
}); | ||
st.equal(count, 0, 'does not call the disposable immediately'); | ||
return instance.disposeAsync().then(function () { | ||
st.equal(count, 2, 'calls the disposable twice, as expected'); | ||
st['throws']( | ||
function () { instance.use(disposable); }, | ||
ReferenceError, | ||
'throws when already disposed: ' + inspect(instance) | ||
); | ||
var badDisposable = {}; | ||
badDisposable[symbolAsyncDispose] = throwsSentinel; | ||
var instance2 = new AsyncDisposableStack(); | ||
instance2.use(badDisposable); | ||
return instance2.disposeAsync(); | ||
}).then( | ||
function () { | ||
st.fail('dispose with a throwing disposable failed to throw'); | ||
}, | ||
function (e) { | ||
st.equal(e, throwSentinel, 'throws `throwSentinel`'); | ||
} | ||
); | ||
}); | ||
t.test('defer', { skip: typeof Promise !== 'function' }, function (st) { | ||
var instance = new AsyncDisposableStack(); | ||
forEach(v.nonFunctions, function (nonFunction) { | ||
st['throws']( | ||
function () { instance.defer(nonFunction); }, | ||
TypeError, | ||
'throws on a nonfunction: ' + inspect(nonFunction) | ||
); | ||
}); | ||
var count = 0; | ||
var increment = function increment() { | ||
count += 1; | ||
}; | ||
instance.defer(increment); | ||
instance.defer(increment); | ||
st.equal(count, 0, 'does not call the disposable immediately'); | ||
return instance.disposeAsync().then(function () { | ||
st.equal(count, 2, 'calls the disposable twice, as expected'); | ||
st['throws']( | ||
function () { instance.defer(function () {}); }, | ||
ReferenceError, | ||
'throws when already disposed: ' + inspect(instance) | ||
); | ||
var instance2 = new AsyncDisposableStack(); | ||
instance2.defer(throwsSentinel); | ||
return instance2.disposeAsync().then( | ||
function () { | ||
st.fail('dispose with a throwing disposable failed to throw'); | ||
}, | ||
function (e) { | ||
st.equal(e, throwSentinel, 'throws `throwSentinel`'); | ||
} | ||
); | ||
}); | ||
}); | ||
t.test('adopt', { skip: typeof Promise !== 'function' }, function (st) { | ||
var instance = new AsyncDisposableStack(); | ||
forEach(v.nonFunctions, function (nonFunction) { | ||
st['throws']( | ||
function () { instance.adopt(nonFunction); }, | ||
TypeError, | ||
'throws on a nonfunction: ' + inspect(nonFunction) | ||
); | ||
}); | ||
var args = []; | ||
var onDisposeAsync = function onDisposeAsync() { | ||
args.push({ | ||
count: arguments.length, | ||
args: Array.prototype.slice.call(arguments) | ||
}); | ||
}; | ||
var sentinel = { sentinel: true }; | ||
instance.adopt(undefined, onDisposeAsync); | ||
instance.adopt(null, onDisposeAsync); | ||
instance.adopt(sentinel, onDisposeAsync); | ||
st.deepEqual(args, [], 'does not call the disposable immediately'); | ||
return instance.disposeAsync().then(function (x) { | ||
st.equal(x, undefined, 'returns undefined'); | ||
st.deepEqual(args, [ | ||
{ count: 1, args: [sentinel] }, | ||
{ count: 1, args: [null] }, | ||
{ count: 1, args: [undefined] } | ||
], 'disposes the adopted things in reverse order'); | ||
st['throws']( | ||
function () { instance.adopt(onDisposeAsync); }, | ||
ReferenceError, | ||
'throws when already disposed: ' + inspect(instance) | ||
); | ||
var instance2 = new AsyncDisposableStack(); | ||
instance2.adopt(null, throwsSentinel); | ||
return instance2.disposeAsync().then( | ||
function () { | ||
st.fail('dispose with a throwing disposable failed to throw'); | ||
}, | ||
function (e) { | ||
st.equal(e, throwSentinel, 'throws `throwSentinel`'); | ||
} | ||
); | ||
}); | ||
}); | ||
t.test('move', { skip: typeof Promise !== 'function' }, function (st) { | ||
var disposed = new AsyncDisposableStack(); | ||
return disposed.disposeAsync().then(function () { | ||
st['throws']( | ||
function () { | ||
disposed.move(); | ||
}, | ||
ReferenceError, | ||
'throws on a disposed AsyncDisposableStack: ' + inspect(disposed) | ||
); | ||
var instance = new AsyncDisposableStack(); | ||
var count = 0; | ||
var increment = function increment() { | ||
count += 1; | ||
}; | ||
instance.defer(increment); | ||
instance.defer(increment); | ||
st.equal(count, 0, '`increment` has not yet been called'); | ||
st.equal(instance.disposed, false, 'old stack is not disposed'); | ||
var newStack = instance.move(); | ||
st.equal(count, 0, '`increment` has not yet been called'); | ||
st.equal(instance.disposed, true, 'old stack is now disposed'); | ||
st.equal(newStack.disposed, false, 'new stack is not disposed'); | ||
return newStack.disposeAsync().then(function () { | ||
st.equal(count, 2, '`increment` has been called exactly twice'); | ||
st.equal(newStack.disposed, true, 'new stack is now disposed'); | ||
}); | ||
}); | ||
}); | ||
t.test('Symbol.asyncDispose', { skip: !symbolAsyncDispose }, function (st) { | ||
st.equal( | ||
AsyncDisposableStack.prototype[symbolAsyncDispose], | ||
AsyncDisposableStack.prototype.disposeAsync, | ||
'is the same function as `disposeAsync`' | ||
); | ||
st.end(); | ||
}); | ||
t.test('dispose', { skip: typeof Promise !== 'function' }, function (st) { | ||
var disposed = new AsyncDisposableStack(); | ||
return disposed.disposeAsync().then(function () { | ||
st.ok(disposed.disposed, 'is disposed'); | ||
return Promise.resolve(disposed.disposeAsync()); | ||
}).then(function (result) { | ||
st.equal(result, undefined, 'disposing a disposed stack returns undefined'); | ||
var instance = new AsyncDisposableStack(); | ||
var count = 0; | ||
var increment = function increment() { | ||
count += 1; | ||
}; | ||
instance.defer(increment); | ||
instance.defer(increment); | ||
st.equal(count, 0, '`increment` has not yet been called'); | ||
st.equal(instance.disposed, false, 'stack is not disposed'); | ||
return Promise.resolve(instance.disposeAsync()).then(function () { | ||
st.equal(count, 2, '`increment` has been called exactly twice'); | ||
st.equal(instance.disposed, true, 'stack is now disposed'); | ||
}); | ||
}); | ||
}); | ||
t.test('toStringTag', { skip: !hasToStringTag() }, function (st) { | ||
var instance = new AsyncDisposableStack(); | ||
st.equal( | ||
Object.prototype.toString.call(instance), | ||
'[object AsyncDisposableStack]', | ||
'has the correct [[Class]]' | ||
); | ||
st.end(); | ||
}); | ||
}, | ||
'Symbol.dispose': function testSymbolDispose(t, symbolDispose) { | ||
@@ -322,3 +616,20 @@ t.test('Symbol support', { skip: !hasSymbols() }, function (st) { | ||
}); | ||
}, | ||
'Symbol.asyncDispose': function testSymbolAsyncDispose(t, symbolAsyncDispose) { | ||
t.test('Symbol support', { skip: !hasSymbols() }, function (st) { | ||
st.ok(isSymbol(symbolAsyncDispose), 'is a symbol'); | ||
st.notOk(isRegisteredSymbol(symbolAsyncDispose), 'is not a registered symbol'); | ||
st.end(); | ||
}); | ||
t.test('no Symbol support', { skip: hasSymbols() }, function (st) { | ||
st.notOk(isSymbol(symbolAsyncDispose), 'is not a symbol'); | ||
st.notOk(isRegisteredSymbol(symbolAsyncDispose), 'is not a registered symbol'); | ||
st.equal(symbolAsyncDispose, null, 'is `null`'); | ||
st.end(); | ||
}); | ||
} | ||
}; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54231
39
1175
69
1
Updatedes-abstract@^1.21.2