@glimmer/destroyable
Advanced tools
Comparing version 0.85.5 to 0.85.6
@@ -1,174 +0,2 @@ | ||
import { scheduleDestroyed, scheduleDestroy } from '@glimmer/global-context'; | ||
import { debugToString } from '@glimmer/util'; | ||
var DestroyingState = /*#__PURE__*/function (DestroyingState) { | ||
DestroyingState[DestroyingState["Live"] = 0] = "Live"; | ||
DestroyingState[DestroyingState["Destroying"] = 1] = "Destroying"; | ||
DestroyingState[DestroyingState["Destroyed"] = 2] = "Destroyed"; | ||
return DestroyingState; | ||
}(DestroyingState || {}); | ||
let DESTROYABLE_META = new WeakMap(); | ||
function push(collection, newItem) { | ||
if (collection === null) { | ||
return newItem; | ||
} else if (Array.isArray(collection)) { | ||
collection.push(newItem); | ||
return collection; | ||
} else { | ||
return [collection, newItem]; | ||
} | ||
} | ||
function iterate(collection, fn) { | ||
if (Array.isArray(collection)) { | ||
collection.forEach(fn); | ||
} else if (collection !== null) { | ||
fn(collection); | ||
} | ||
} | ||
function remove(collection, item, message) { | ||
{ | ||
let collectionIsItem = collection === item; | ||
let collectionContainsItem = Array.isArray(collection) && collection.indexOf(item) !== -1; | ||
if (!collectionIsItem && !collectionContainsItem) { | ||
throw new Error(String(message)); | ||
} | ||
} | ||
if (Array.isArray(collection) && collection.length > 1) { | ||
let index = collection.indexOf(item); | ||
collection.splice(index, 1); | ||
return collection; | ||
} else { | ||
return null; | ||
} | ||
} | ||
function getDestroyableMeta(destroyable) { | ||
let meta = DESTROYABLE_META.get(destroyable); | ||
if (meta === undefined) { | ||
meta = { | ||
parents: null, | ||
children: null, | ||
eagerDestructors: null, | ||
destructors: null, | ||
state: DestroyingState.Live | ||
}; | ||
{ | ||
meta.source = destroyable; | ||
} | ||
DESTROYABLE_META.set(destroyable, meta); | ||
} | ||
return meta; | ||
} | ||
function associateDestroyableChild(parent, child) { | ||
if (isDestroying(parent)) { | ||
throw new Error('Attempted to associate a destroyable child with an object that is already destroying or destroyed'); | ||
} | ||
let parentMeta = getDestroyableMeta(parent); | ||
let childMeta = getDestroyableMeta(child); | ||
parentMeta.children = push(parentMeta.children, child); | ||
childMeta.parents = push(childMeta.parents, parent); | ||
return child; | ||
} | ||
function registerDestructor(destroyable, destructor) { | ||
let eager = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; | ||
if (isDestroying(destroyable)) { | ||
throw new Error('Attempted to register a destructor with an object that is already destroying or destroyed'); | ||
} | ||
let meta = getDestroyableMeta(destroyable); | ||
let destructorsKey = eager === true ? 'eagerDestructors' : 'destructors'; | ||
meta[destructorsKey] = push(meta[destructorsKey], destructor); | ||
return destructor; | ||
} | ||
function unregisterDestructor(destroyable, destructor) { | ||
let eager = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; | ||
if (isDestroying(destroyable)) { | ||
throw new Error('Attempted to unregister a destructor with an object that is already destroying or destroyed'); | ||
} | ||
let meta = getDestroyableMeta(destroyable); | ||
let destructorsKey = eager === true ? 'eagerDestructors' : 'destructors'; | ||
meta[destructorsKey] = remove(meta[destructorsKey], destructor, 'attempted to remove a destructor that was not registered with the destroyable'); | ||
} | ||
//////////// | ||
function destroy(destroyable) { | ||
let meta = getDestroyableMeta(destroyable); | ||
if (meta.state >= DestroyingState.Destroying) return; | ||
let { | ||
parents, | ||
children, | ||
eagerDestructors, | ||
destructors | ||
} = meta; | ||
meta.state = DestroyingState.Destroying; | ||
iterate(children, destroy); | ||
iterate(eagerDestructors, destructor => destructor(destroyable)); | ||
iterate(destructors, destructor => scheduleDestroy(destroyable, destructor)); | ||
scheduleDestroyed(() => { | ||
iterate(parents, parent => removeChildFromParent(destroyable, parent)); | ||
meta.state = DestroyingState.Destroyed; | ||
}); | ||
} | ||
function removeChildFromParent(child, parent) { | ||
let parentMeta = getDestroyableMeta(parent); | ||
if (parentMeta.state === DestroyingState.Live) { | ||
parentMeta.children = remove(parentMeta.children, child, "attempted to remove child from parent, but the parent's children did not contain the child. This is likely a bug with destructors."); | ||
} | ||
} | ||
function destroyChildren(destroyable) { | ||
let { | ||
children | ||
} = getDestroyableMeta(destroyable); | ||
iterate(children, destroy); | ||
} | ||
function _hasDestroyableChildren(destroyable) { | ||
let meta = DESTROYABLE_META.get(destroyable); | ||
return meta === undefined ? false : meta.children !== null; | ||
} | ||
function isDestroying(destroyable) { | ||
let meta = DESTROYABLE_META.get(destroyable); | ||
return meta === undefined ? false : meta.state >= DestroyingState.Destroying; | ||
} | ||
function isDestroyed(destroyable) { | ||
let meta = DESTROYABLE_META.get(destroyable); | ||
return meta === undefined ? false : meta.state >= DestroyingState.Destroyed; | ||
} | ||
//////////// | ||
let enableDestroyableTracking; | ||
let assertDestroyablesDestroyed; | ||
{ | ||
let isTesting = false; | ||
enableDestroyableTracking = () => { | ||
if (isTesting) { | ||
// Reset destroyable meta just in case, before throwing the error | ||
DESTROYABLE_META = new WeakMap(); | ||
throw new Error('Attempted to start destroyable testing, but you did not end the previous destroyable test. Did you forget to call `assertDestroyablesDestroyed()`'); | ||
} | ||
isTesting = true; | ||
DESTROYABLE_META = new Map(); | ||
}; | ||
assertDestroyablesDestroyed = () => { | ||
if (!isTesting) { | ||
throw new Error('Attempted to assert destroyables destroyed, but you did not start a destroyable test. Did you forget to call `enableDestroyableTracking()`'); | ||
} | ||
isTesting = false; | ||
let map = DESTROYABLE_META; | ||
DESTROYABLE_META = new WeakMap(); | ||
let undestroyed = []; | ||
map.forEach(meta => { | ||
if (meta.state !== DestroyingState.Destroyed) { | ||
undestroyed.push(meta.source); | ||
} | ||
}); | ||
if (undestroyed.length > 0) { | ||
let objectsToString = undestroyed.map(debugToString).join('\n '); | ||
let error = new Error(`Some destroyables were not destroyed during this test:\n ${objectsToString}`); | ||
error.destroyables = undestroyed; | ||
throw error; | ||
} | ||
}; | ||
} | ||
export { _hasDestroyableChildren, assertDestroyablesDestroyed, associateDestroyableChild, destroy, destroyChildren, enableDestroyableTracking, isDestroyed, isDestroying, registerDestructor, unregisterDestructor }; | ||
import{scheduleDestroyed as t,scheduleDestroy as e}from"@glimmer/global-context";import{debugToString as r}from"@glimmer/util";var o=function(t){return t[t.Live=0]="Live",t[t.Destroying=1]="Destroying",t[t.Destroyed=2]="Destroyed",t}(o||{});let n,s,i=new WeakMap;function a(t,e){return null===t?e:Array.isArray(t)?(t.push(e),t):[t,e]}function l(t,e){Array.isArray(t)?t.forEach(e):null!==t&&e(t)}function d(t,e,r){{let o=t===e,n=Array.isArray(t)&&-1!==t.indexOf(e);if(!o&&!n)throw new Error(String(r))}if(Array.isArray(t)&&t.length>1){let r=t.indexOf(e);return t.splice(r,1),t}return null}function u(t){let e=i.get(t);return void 0===e&&(e={parents:null,children:null,eagerDestructors:null,destructors:null,state:o.Live},e.source=t,i.set(t,e)),e}function c(t,e){if(w(t))throw new Error("Attempted to associate a destroyable child with an object that is already destroying or destroyed");let r=u(t),o=u(e);return r.children=a(r.children,e),o.parents=a(o.parents,t),e}function y(t,e){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(w(t))throw new Error("Attempted to register a destructor with an object that is already destroying or destroyed");let o=u(t),n=!0===r?"eagerDestructors":"destructors";return o[n]=a(o[n],e),e}function h(t,e){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(w(t))throw new Error("Attempted to unregister a destructor with an object that is already destroying or destroyed");let o=u(t),n=!0===r?"eagerDestructors":"destructors";o[n]=d(o[n],e,"attempted to remove a destructor that was not registered with the destroyable")}function g(r){let n=u(r);if(n.state>=o.Destroying)return;let{parents:s,children:i,eagerDestructors:a,destructors:c}=n;n.state=o.Destroying,l(i,g),l(a,(t=>t(r))),l(c,(t=>e(r,t))),t((()=>{l(s,(t=>function(t,e){let r=u(e);r.state===o.Live&&(r.children=d(r.children,t,"attempted to remove child from parent, but the parent's children did not contain the child. This is likely a bug with destructors."))}(r,t))),n.state=o.Destroyed}))}function f(t){let{children:e}=u(t);l(e,g)}function p(t){let e=i.get(t);return void 0!==e&&null!==e.children}function w(t){let e=i.get(t);return void 0!==e&&e.state>=o.Destroying}function m(t){let e=i.get(t);return void 0!==e&&e.state>=o.Destroyed}{let t=!1;n=()=>{if(t)throw i=new WeakMap,new Error("Attempted to start destroyable testing, but you did not end the previous destroyable test. Did you forget to call `assertDestroyablesDestroyed()`");t=!0,i=new Map},s=()=>{if(!t)throw new Error("Attempted to assert destroyables destroyed, but you did not start a destroyable test. Did you forget to call `enableDestroyableTracking()`");t=!1;let e=i;i=new WeakMap;let n=[];if(e.forEach((t=>{t.state!==o.Destroyed&&n.push(t.source)})),n.length>0){let t=n.map(r).join("\n "),e=new Error(`Some destroyables were not destroyed during this test:\n ${t}`);throw e.destroyables=n,e}}}export{p as _hasDestroyableChildren,s as assertDestroyablesDestroyed,c as associateDestroyableChild,g as destroy,f as destroyChildren,n as enableDestroyableTracking,m as isDestroyed,w as isDestroying,y as registerDestructor,h as unregisterDestructor}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@glimmer/destroyable", | ||
"type": "module", | ||
"version": "0.85.5", | ||
"version": "0.85.6", | ||
"repository": "https://github.com/glimmerjs/glimmer-vm/tree/master/packages/@glimmer/destroyable", | ||
@@ -18,5 +18,5 @@ "description": "Utilities for creating and managing a destroyable hierarchy of objects", | ||
"@glimmer/env": "0.1.7", | ||
"@glimmer/global-context": "^0.85.5", | ||
"@glimmer/interfaces": "^0.85.5", | ||
"@glimmer/util": "^0.85.5" | ||
"@glimmer/global-context": "^0.85.6", | ||
"@glimmer/interfaces": "^0.85.6", | ||
"@glimmer/util": "^0.85.6" | ||
}, | ||
@@ -27,3 +27,3 @@ "devDependencies": { | ||
"publint": "^0.2.5", | ||
"@glimmer/local-debug-flags": "^0.85.5", | ||
"@glimmer/local-debug-flags": "^0.85.6", | ||
"@glimmer-workspace/build-support": "^1.0.0" | ||
@@ -30,0 +30,0 @@ }, |
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
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
35187
409
Updated@glimmer/interfaces@^0.85.6
Updated@glimmer/util@^0.85.6