@flighthq/node 0.3.0-next.1595.4d49b41 → 0.3.0-next.1665.6235922

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@ export * from './hasTransform3d';
9
9
  export * from './hierarchy';
10
10
  export * from './node';
11
11
  export * from './nodeColorAdjustment';
12
+ export * from './nodeOrderList';
12
13
  export * from './revision';
13
14
  export * from './nodeTransform2d';
14
15
  export * from './stageFit';
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
package/dist/contract.js CHANGED
@@ -9,6 +9,7 @@ export * from './hasTransform3d';
9
9
  export * from './hierarchy';
10
10
  export * from './node';
11
11
  export * from './nodeColorAdjustment';
12
+ export * from './nodeOrderList';
12
13
  export * from './revision';
13
14
  export * from './nodeTransform2d';
14
15
  export * from './stageFit';
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { addNodeChild, addNodeChildAt, addNodeChildren, addNodeColorAdjustment, computeNodeBoundsRectangle, computeNodeRootLocalBoundsRectangle, computeScene2DFitAlignX, computeScene2DFitAlignY, computeScene2DFitFillScale, computeScene2DFitScale, computeScene2DFitTransform, containsNodeChild, convertNodeVector2GlobalToLocal, convertNodeVector2LocalToGlobal, convertNodeVector3GlobalToLocal, convertNodeVector3LocalToGlobal, createNode, createViewport, disposeNode, enableNodeSignals, findNode, findNodeByName, forEachNodeAncestor, forEachNodeChild, forEachNodeDescendant, getNodeAncestors, getNodeAppearanceRevision, getNodeChildAt, getNodeChildByName, getNodeChildCount, getNodeChildIndex, getNodeChildren, getNodeColorAdjustments, getNodeCommonAncestor, getNodeDepth, getNodeHeight, getNodeLocalBoundsRectangle, getNodeLocalBoundsRevision, getNodeLocalContentRevision, getNodeLocalMatrix, getNodeLocalMatrix4, getNodeLocalTransformRevision, getNodeNextSibling, getNodeParent, getNodeParentBoundsRectangle, getNodePreviousSibling, getNodeRoot, getNodeSignals, getNodeTransform2D, getNodeTransform3D, getNodeWidth, getNodeWorldBoundsRectangle, getNodeWorldMatrix, getNodeWorldMatrix4, getNodeWorldTransformRevision, getViewportAspect, invalidateNodeAppearance, invalidateNodeLocalTransform, invalidateNodeRender, isNodeAncestorOf, isNodeLocalMatrix4Detached, removeNodeChild, removeNodeChildAt, removeNodeChildren, reparentNode, replaceNodeChild, setNodeChildIndex, setNodeColorAdjustments, setNodeColorAdjustmentsTint, setNodeEnabled, setNodeHeight, setNodeLocalMatrix, setNodeLocalMatrix4, setNodeTransform2D, setNodeTransform3D, setNodeWidth, swapNodeChildren, swapNodeChildrenAt, walkNodeDescendants, } from './contract';
1
+ export { addNodeChild, addNodeChildAt, addNodeChildren, addNodeColorAdjustment, addNodeOrderListEntry, applyNodeOrderList, computeNodeBoundsRectangle, computeNodeRootLocalBoundsRectangle, computeScene2DFitAlignX, computeScene2DFitAlignY, computeScene2DFitFillScale, computeScene2DFitScale, computeScene2DFitTransform, clearNodeOrderList, containsNodeChild, convertNodeVector2GlobalToLocal, convertNodeVector2LocalToGlobal, convertNodeVector3GlobalToLocal, convertNodeVector3LocalToGlobal, createNode, createNodeOrderList, createViewport, disposeNode, enableNodeSignals, findNode, findNodeByName, forEachNodeAncestor, forEachNodeChild, forEachNodeDescendant, getNodeAncestors, getNodeAppearanceRevision, getNodeChildAt, getNodeChildByName, getNodeChildCount, getNodeChildIndex, getNodeChildren, getNodeColorAdjustments, getNodeCommonAncestor, getNodeDepth, getNodeHeight, getNodeLocalBoundsRectangle, getNodeLocalBoundsRevision, getNodeLocalContentRevision, getNodeLocalMatrix, getNodeLocalMatrix4, getNodeLocalTransformRevision, getNodeNextSibling, getNodeParent, getNodeParentBoundsRectangle, getNodePreviousSibling, getNodeRoot, getNodeSignals, getNodeTransform2D, getNodeTransform3D, getNodeWidth, getNodeWorldBoundsRectangle, getNodeWorldMatrix, getNodeWorldMatrix4, getNodeWorldTransformRevision, getViewportAspect, invalidateNodeAppearance, invalidateNodeLocalTransform, invalidateNodeRender, isNodeAncestorOf, isNodeLocalMatrix4Detached, removeNodeChild, removeNodeChildAt, removeNodeChildren, reparentNode, replaceNodeChild, setNodeChildIndex, setNodeColorAdjustments, setNodeColorAdjustmentsTint, setNodeEnabled, setNodeHeight, setNodeLocalMatrix, setNodeLocalMatrix4, setNodeTransform2D, setNodeTransform3D, setNodeWidth, swapNodeChildren, swapNodeChildrenAt, walkNodeDescendants, disposeNodeOrderList, forEachNodeOrderListEntry, getNodeOrderListEntrySortKey, hasNodeOrderListEntry, removeNodeOrderListEntry, setNodeOrderListEntry, setNodeOrderListEntryAbove, setNodeOrderListEntryBelow, setNodeOrderListFromNodeChildren, swapNodeOrderListEntries, } from './contract';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,0BAA0B,EAC1B,mCAAmC,EACnC,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,iBAAiB,EACjB,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,UAAU,EACV,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,aAAa,EACb,4BAA4B,EAC5B,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,wBAAwB,EACxB,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,mCAAmC,EACnC,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,aAAa,EACb,4BAA4B,EAC5B,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,wBAAwB,EACxB,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,gCAAgC,EAChC,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { addNodeChild, addNodeChildAt, addNodeChildren, addNodeColorAdjustment, computeNodeBoundsRectangle, computeNodeRootLocalBoundsRectangle, computeScene2DFitAlignX, computeScene2DFitAlignY, computeScene2DFitFillScale, computeScene2DFitScale, computeScene2DFitTransform, containsNodeChild, convertNodeVector2GlobalToLocal, convertNodeVector2LocalToGlobal, convertNodeVector3GlobalToLocal, convertNodeVector3LocalToGlobal, createNode, createViewport, disposeNode, enableNodeSignals, findNode, findNodeByName, forEachNodeAncestor, forEachNodeChild, forEachNodeDescendant, getNodeAncestors, getNodeAppearanceRevision, getNodeChildAt, getNodeChildByName, getNodeChildCount, getNodeChildIndex, getNodeChildren, getNodeColorAdjustments, getNodeCommonAncestor, getNodeDepth, getNodeHeight, getNodeLocalBoundsRectangle, getNodeLocalBoundsRevision, getNodeLocalContentRevision, getNodeLocalMatrix, getNodeLocalMatrix4, getNodeLocalTransformRevision, getNodeNextSibling, getNodeParent, getNodeParentBoundsRectangle, getNodePreviousSibling, getNodeRoot, getNodeSignals, getNodeTransform2D, getNodeTransform3D, getNodeWidth, getNodeWorldBoundsRectangle, getNodeWorldMatrix, getNodeWorldMatrix4, getNodeWorldTransformRevision, getViewportAspect, invalidateNodeAppearance, invalidateNodeLocalTransform, invalidateNodeRender, isNodeAncestorOf, isNodeLocalMatrix4Detached, removeNodeChild, removeNodeChildAt, removeNodeChildren, reparentNode, replaceNodeChild, setNodeChildIndex, setNodeColorAdjustments, setNodeColorAdjustmentsTint, setNodeEnabled, setNodeHeight, setNodeLocalMatrix, setNodeLocalMatrix4, setNodeTransform2D, setNodeTransform3D, setNodeWidth, swapNodeChildren, swapNodeChildrenAt, walkNodeDescendants, } from './contract';
1
+ export { addNodeChild, addNodeChildAt, addNodeChildren, addNodeColorAdjustment, addNodeOrderListEntry, applyNodeOrderList, computeNodeBoundsRectangle, computeNodeRootLocalBoundsRectangle, computeScene2DFitAlignX, computeScene2DFitAlignY, computeScene2DFitFillScale, computeScene2DFitScale, computeScene2DFitTransform, clearNodeOrderList, containsNodeChild, convertNodeVector2GlobalToLocal, convertNodeVector2LocalToGlobal, convertNodeVector3GlobalToLocal, convertNodeVector3LocalToGlobal, createNode, createNodeOrderList, createViewport, disposeNode, enableNodeSignals, findNode, findNodeByName, forEachNodeAncestor, forEachNodeChild, forEachNodeDescendant, getNodeAncestors, getNodeAppearanceRevision, getNodeChildAt, getNodeChildByName, getNodeChildCount, getNodeChildIndex, getNodeChildren, getNodeColorAdjustments, getNodeCommonAncestor, getNodeDepth, getNodeHeight, getNodeLocalBoundsRectangle, getNodeLocalBoundsRevision, getNodeLocalContentRevision, getNodeLocalMatrix, getNodeLocalMatrix4, getNodeLocalTransformRevision, getNodeNextSibling, getNodeParent, getNodeParentBoundsRectangle, getNodePreviousSibling, getNodeRoot, getNodeSignals, getNodeTransform2D, getNodeTransform3D, getNodeWidth, getNodeWorldBoundsRectangle, getNodeWorldMatrix, getNodeWorldMatrix4, getNodeWorldTransformRevision, getViewportAspect, invalidateNodeAppearance, invalidateNodeLocalTransform, invalidateNodeRender, isNodeAncestorOf, isNodeLocalMatrix4Detached, removeNodeChild, removeNodeChildAt, removeNodeChildren, reparentNode, replaceNodeChild, setNodeChildIndex, setNodeColorAdjustments, setNodeColorAdjustmentsTint, setNodeEnabled, setNodeHeight, setNodeLocalMatrix, setNodeLocalMatrix4, setNodeTransform2D, setNodeTransform3D, setNodeWidth, swapNodeChildren, swapNodeChildrenAt, walkNodeDescendants, disposeNodeOrderList, forEachNodeOrderListEntry, getNodeOrderListEntrySortKey, hasNodeOrderListEntry, removeNodeOrderListEntry, setNodeOrderListEntry, setNodeOrderListEntryAbove, setNodeOrderListEntryBelow, setNodeOrderListFromNodeChildren, swapNodeOrderListEntries, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,0BAA0B,EAC1B,mCAAmC,EACnC,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,iBAAiB,EACjB,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,UAAU,EACV,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,aAAa,EACb,4BAA4B,EAC5B,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,wBAAwB,EACxB,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,mCAAmC,EACnC,uBAAuB,EACvB,uBAAuB,EACvB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,kBAAkB,EAClB,aAAa,EACb,4BAA4B,EAC5B,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,2BAA2B,EAC3B,kBAAkB,EAClB,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,EACjB,wBAAwB,EACxB,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,gCAAgC,EAChC,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,88 @@
1
+ import type { Node, NodeOrderList, NodeOrderListEntryVisitor, NodeTraits } from '@flighthq/types/contract';
2
+ /**
3
+ * Appends one entry to the list's valid window. Capacity past `entryCount` is reused, so a list
4
+ * refilled every frame allocates only while it is growing. This does not check whether `node` is
5
+ * already entered — it is the O(1) bulk-fill verb. Use setNodeOrderListEntry to re-key a node that may
6
+ * already be present; a node entered twice resolves to its last entry.
7
+ */
8
+ export declare function addNodeOrderListEntry<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, node: Node<Traits>, sortKey: number): void;
9
+ /**
10
+ * Reorders `target`'s children so the list's members sit in ascending sort-key order, and does nothing
11
+ * else. This owns order, never membership: members are permuted among the slots they already occupy, so
12
+ * a child the list does not name never moves, not by one index. Entries that are not currently children
13
+ * of `target` — including ones attached to a different parent — are ignored rather than attached, which
14
+ * makes the call a no-op once the caller has detached every member.
15
+ *
16
+ * Because slots are preserved rather than compacted, a foreign child sitting between two members stays
17
+ * between them; no sort key moves a member past it. Contiguity comes from parenting, relative order
18
+ * from the list.
19
+ *
20
+ * Children are written in place rather than routed through setNodeChildIndex: every member is already a
21
+ * child of `target`, so no parent pointer or parentReferenceId changes, and the whole permutation stamps
22
+ * `childrenId` once instead of once per moved node.
23
+ */
24
+ export declare function applyNodeOrderList<Traits extends object = NodeTraits>(target: Node<Traits>, list: Readonly<NodeOrderList<Traits>>): void;
25
+ /**
26
+ * Empties the valid window without releasing capacity, so the next fill reuses the arrays. Entries past
27
+ * `entryCount` keep their node references; use disposeNodeOrderList to drop them.
28
+ */
29
+ export declare function clearNodeOrderList<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>): void;
30
+ export declare function createNodeOrderList<Traits extends object = NodeTraits>(): NodeOrderList<Traits>;
31
+ /**
32
+ * Empties the list and releases its node references, so a long-lived list stops holding nodes reachable.
33
+ * The list stays usable; this is the teardown counterpart to clearNodeOrderList, which deliberately
34
+ * retains both capacity and the references past the window for reuse.
35
+ */
36
+ export declare function disposeNodeOrderList<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>): void;
37
+ /**
38
+ * Calls `callback` for each entry in the order the entries were added, which is not the order they
39
+ * resolve to. Stops early if `callback` returns `false`.
40
+ */
41
+ export declare function forEachNodeOrderListEntry<Traits extends object = NodeTraits>(list: Readonly<NodeOrderList<Traits>>, callback: NodeOrderListEntryVisitor<Traits>): void;
42
+ /**
43
+ * Returns the sort key `node` is entered with, or `null` when it has no entry. Null rather than -1
44
+ * because every finite number, negative included, is a legal sort key.
45
+ */
46
+ export declare function getNodeOrderListEntrySortKey<Traits extends object = NodeTraits>(list: Readonly<NodeOrderList<Traits>>, node: Readonly<Node<Traits>>): number | null;
47
+ export declare function hasNodeOrderListEntry<Traits extends object = NodeTraits>(list: Readonly<NodeOrderList<Traits>>, node: Readonly<Node<Traits>>): boolean;
48
+ /**
49
+ * Removes `node`'s entry, returning whether one was found. Entries after it shift down rather than
50
+ * being back-filled from the end: entry position breaks ties between equal sort keys, so preserving it
51
+ * is part of the contract, not an implementation detail.
52
+ */
53
+ export declare function removeNodeOrderListEntry<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, node: Readonly<Node<Traits>>): boolean;
54
+ /**
55
+ * Enters `node` at `sortKey`, replacing its existing entry in place if it has one. This is the verb for
56
+ * incremental re-keying: unlike addNodeOrderListEntry it never grows the list with a second entry for
57
+ * the same node, at the cost of a scan.
58
+ */
59
+ export declare function setNodeOrderListEntry<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, node: Node<Traits>, sortKey: number): void;
60
+ /**
61
+ * Enters `node` so it resolves immediately above `target` — drawn after it, in front of it. Does
62
+ * nothing when `target` has no entry, since there is nothing to be above.
63
+ *
64
+ * Placement is exact rather than a midpoint between neighbouring keys: `node` takes `target`'s own sort
65
+ * key and its entry is positioned just after `target`'s, so the equal-key tie-break separates the two.
66
+ * That holds however tightly packed the surrounding keys are, and repeated placement never exhausts
67
+ * float precision the way bisection does.
68
+ */
69
+ export declare function setNodeOrderListEntryAbove<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, node: Node<Traits>, target: Readonly<Node<Traits>>): void;
70
+ /**
71
+ * Enters `node` so it resolves immediately below `target` — drawn before it, behind it. Does nothing
72
+ * when `target` has no entry. The mirror of setNodeOrderListEntryAbove, placing `node`'s entry just
73
+ * before `target`'s at the same sort key.
74
+ */
75
+ export declare function setNodeOrderListEntryBelow<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, node: Node<Traits>, target: Readonly<Node<Traits>>): void;
76
+ /**
77
+ * Refills the list from `source`'s current children, each entered at its own child index. This is the
78
+ * inverse of applyNodeOrderList: capture what is there, edit it with the *Above/*Below/swap verbs, then
79
+ * apply it back. Any previous contents are discarded.
80
+ */
81
+ export declare function setNodeOrderListFromNodeChildren<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, source: Readonly<Node<Traits>>): void;
82
+ /**
83
+ * Exchanges the sort keys of two entered nodes, the way a display list swaps two depths. Does nothing
84
+ * unless both nodes have entries. Entry positions are left alone, so a tie between the two resolves the
85
+ * same way afterwards as before.
86
+ */
87
+ export declare function swapNodeOrderListEntries<Traits extends object = NodeTraits>(list: NodeOrderList<Traits>, nodeA: Readonly<Node<Traits>>, nodeB: Readonly<Node<Traits>>): void;
88
+ //# sourceMappingURL=nodeOrderList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeOrderList.d.ts","sourceRoot":"","sources":["../src/nodeOrderList.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,250 @@
1
+ import { emitSignal } from '@flighthq/signals/contract';
2
+ import { getNodeRuntime } from './node';
3
+ /**
4
+ * Appends one entry to the list's valid window. Capacity past `entryCount` is reused, so a list
5
+ * refilled every frame allocates only while it is growing. This does not check whether `node` is
6
+ * already entered — it is the O(1) bulk-fill verb. Use setNodeOrderListEntry to re-key a node that may
7
+ * already be present; a node entered twice resolves to its last entry.
8
+ */
9
+ export function addNodeOrderListEntry(list, node, sortKey) {
10
+ const entryCount = list.entryCount;
11
+ if (entryCount < list.nodes.length) {
12
+ list.nodes[entryCount] = node;
13
+ list.sortKeys[entryCount] = sortKey;
14
+ }
15
+ else {
16
+ list.nodes.push(node);
17
+ list.sortKeys.push(sortKey);
18
+ }
19
+ list.entryCount = entryCount + 1;
20
+ }
21
+ /**
22
+ * Reorders `target`'s children so the list's members sit in ascending sort-key order, and does nothing
23
+ * else. This owns order, never membership: members are permuted among the slots they already occupy, so
24
+ * a child the list does not name never moves, not by one index. Entries that are not currently children
25
+ * of `target` — including ones attached to a different parent — are ignored rather than attached, which
26
+ * makes the call a no-op once the caller has detached every member.
27
+ *
28
+ * Because slots are preserved rather than compacted, a foreign child sitting between two members stays
29
+ * between them; no sort key moves a member past it. Contiguity comes from parenting, relative order
30
+ * from the list.
31
+ *
32
+ * Children are written in place rather than routed through setNodeChildIndex: every member is already a
33
+ * child of `target`, so no parent pointer or parentReferenceId changes, and the whole permutation stamps
34
+ * `childrenId` once instead of once per moved node.
35
+ */
36
+ export function applyNodeOrderList(target, list) {
37
+ const targetRuntime = getNodeRuntime(target);
38
+ const children = targetRuntime.children;
39
+ if (children === null || list.entryCount === 0)
40
+ return;
41
+ const listIndex = _listIndex;
42
+ const members = _members;
43
+ const slots = _slots;
44
+ listIndex.clear();
45
+ members.length = 0;
46
+ slots.length = 0;
47
+ // A node entered more than once resolves to its last entry, since the later set overwrites.
48
+ for (let i = 0; i < list.entryCount; i++)
49
+ listIndex.set(list.nodes[i], i);
50
+ for (let i = 0; i < children.length; i++) {
51
+ if (!listIndex.has(children[i]))
52
+ continue;
53
+ members.push(children[i]);
54
+ slots.push(i);
55
+ }
56
+ // Fewer than two members present cannot be a reordering, whatever their sort keys say.
57
+ if (members.length < 2) {
58
+ listIndex.clear();
59
+ members.length = 0;
60
+ return;
61
+ }
62
+ const sortKeys = list.sortKeys;
63
+ members.sort((a, b) => {
64
+ const ai = listIndex.get(a);
65
+ const bi = listIndex.get(b);
66
+ // Equal sort keys keep the order the entries were added in, so a tie is resolved by the list rather
67
+ // than by whatever order the children happened to already be in. Breaking the tie explicitly also
68
+ // frees the C port from needing its sort to be stable, and it is the mechanism the *Above/*Below
69
+ // verbs place with — they assign an equal key and rely on entry position to separate the two.
70
+ return sortKeys[ai] !== sortKeys[bi] ? sortKeys[ai] - sortKeys[bi] : ai - bi;
71
+ });
72
+ let moved = false;
73
+ for (let i = 0; i < slots.length; i++) {
74
+ const slot = slots[i];
75
+ if (children[slot] === members[i])
76
+ continue;
77
+ children[slot] = members[i];
78
+ moved = true;
79
+ }
80
+ // Released before the signal, so a handler that applies another list is not reading this call's
81
+ // scratch out from under it.
82
+ listIndex.clear();
83
+ members.length = 0;
84
+ if (!moved)
85
+ return;
86
+ targetRuntime.childrenId = (targetRuntime.childrenId + 1) >>> 0;
87
+ const targetSignals = targetRuntime.nodeSignals;
88
+ if (targetSignals !== null)
89
+ emitSignal(targetSignals.onChildrenOrderChanged);
90
+ }
91
+ /**
92
+ * Empties the valid window without releasing capacity, so the next fill reuses the arrays. Entries past
93
+ * `entryCount` keep their node references; use disposeNodeOrderList to drop them.
94
+ */
95
+ export function clearNodeOrderList(list) {
96
+ list.entryCount = 0;
97
+ }
98
+ export function createNodeOrderList() {
99
+ return { entryCount: 0, nodes: [], sortKeys: [] };
100
+ }
101
+ /**
102
+ * Empties the list and releases its node references, so a long-lived list stops holding nodes reachable.
103
+ * The list stays usable; this is the teardown counterpart to clearNodeOrderList, which deliberately
104
+ * retains both capacity and the references past the window for reuse.
105
+ */
106
+ export function disposeNodeOrderList(list) {
107
+ list.entryCount = 0;
108
+ list.nodes.length = 0;
109
+ list.sortKeys.length = 0;
110
+ }
111
+ /**
112
+ * Calls `callback` for each entry in the order the entries were added, which is not the order they
113
+ * resolve to. Stops early if `callback` returns `false`.
114
+ */
115
+ export function forEachNodeOrderListEntry(list, callback) {
116
+ for (let i = 0; i < list.entryCount; i++) {
117
+ if (callback(list.nodes[i], list.sortKeys[i], i) === false)
118
+ return;
119
+ }
120
+ }
121
+ /**
122
+ * Returns the sort key `node` is entered with, or `null` when it has no entry. Null rather than -1
123
+ * because every finite number, negative included, is a legal sort key.
124
+ */
125
+ export function getNodeOrderListEntrySortKey(list, node) {
126
+ const index = findNodeOrderListEntryIndex(list, node);
127
+ return index === -1 ? null : list.sortKeys[index];
128
+ }
129
+ export function hasNodeOrderListEntry(list, node) {
130
+ return findNodeOrderListEntryIndex(list, node) !== -1;
131
+ }
132
+ /**
133
+ * Removes `node`'s entry, returning whether one was found. Entries after it shift down rather than
134
+ * being back-filled from the end: entry position breaks ties between equal sort keys, so preserving it
135
+ * is part of the contract, not an implementation detail.
136
+ */
137
+ export function removeNodeOrderListEntry(list, node) {
138
+ const index = findNodeOrderListEntryIndex(list, node);
139
+ if (index === -1)
140
+ return false;
141
+ removeNodeOrderListEntryAtIndex(list, index);
142
+ return true;
143
+ }
144
+ /**
145
+ * Enters `node` at `sortKey`, replacing its existing entry in place if it has one. This is the verb for
146
+ * incremental re-keying: unlike addNodeOrderListEntry it never grows the list with a second entry for
147
+ * the same node, at the cost of a scan.
148
+ */
149
+ export function setNodeOrderListEntry(list, node, sortKey) {
150
+ const index = findNodeOrderListEntryIndex(list, node);
151
+ if (index === -1) {
152
+ addNodeOrderListEntry(list, node, sortKey);
153
+ return;
154
+ }
155
+ list.sortKeys[index] = sortKey;
156
+ }
157
+ /**
158
+ * Enters `node` so it resolves immediately above `target` — drawn after it, in front of it. Does
159
+ * nothing when `target` has no entry, since there is nothing to be above.
160
+ *
161
+ * Placement is exact rather than a midpoint between neighbouring keys: `node` takes `target`'s own sort
162
+ * key and its entry is positioned just after `target`'s, so the equal-key tie-break separates the two.
163
+ * That holds however tightly packed the surrounding keys are, and repeated placement never exhausts
164
+ * float precision the way bisection does.
165
+ */
166
+ export function setNodeOrderListEntryAbove(list, node, target) {
167
+ insertNodeOrderListEntryBeside(list, node, target, 1);
168
+ }
169
+ /**
170
+ * Enters `node` so it resolves immediately below `target` — drawn before it, behind it. Does nothing
171
+ * when `target` has no entry. The mirror of setNodeOrderListEntryAbove, placing `node`'s entry just
172
+ * before `target`'s at the same sort key.
173
+ */
174
+ export function setNodeOrderListEntryBelow(list, node, target) {
175
+ insertNodeOrderListEntryBeside(list, node, target, 0);
176
+ }
177
+ /**
178
+ * Refills the list from `source`'s current children, each entered at its own child index. This is the
179
+ * inverse of applyNodeOrderList: capture what is there, edit it with the *Above/*Below/swap verbs, then
180
+ * apply it back. Any previous contents are discarded.
181
+ */
182
+ export function setNodeOrderListFromNodeChildren(list, source) {
183
+ list.entryCount = 0;
184
+ const children = getNodeRuntime(source).children;
185
+ if (children === null)
186
+ return;
187
+ for (let i = 0; i < children.length; i++) {
188
+ addNodeOrderListEntry(list, children[i], i);
189
+ }
190
+ }
191
+ /**
192
+ * Exchanges the sort keys of two entered nodes, the way a display list swaps two depths. Does nothing
193
+ * unless both nodes have entries. Entry positions are left alone, so a tie between the two resolves the
194
+ * same way afterwards as before.
195
+ */
196
+ export function swapNodeOrderListEntries(list, nodeA, nodeB) {
197
+ const indexA = findNodeOrderListEntryIndex(list, nodeA);
198
+ if (indexA === -1)
199
+ return;
200
+ const indexB = findNodeOrderListEntryIndex(list, nodeB);
201
+ if (indexB === -1)
202
+ return;
203
+ const sortKeyA = list.sortKeys[indexA];
204
+ list.sortKeys[indexA] = list.sortKeys[indexB];
205
+ list.sortKeys[indexB] = sortKeyA;
206
+ }
207
+ function findNodeOrderListEntryIndex(list, node) {
208
+ // Scans backwards so a node entered more than once reports the entry that wins at apply time.
209
+ for (let i = list.entryCount - 1; i >= 0; i--) {
210
+ if (list.nodes[i] === node)
211
+ return i;
212
+ }
213
+ return -1;
214
+ }
215
+ // Shared by the Above (offset 1) and Below (offset 0) verbs: `node` takes `target`'s sort key and its
216
+ // entry lands on the named side of `target`'s. An existing entry for `node` is removed first, so
217
+ // re-placing a node already in the list moves it rather than duplicating it.
218
+ function insertNodeOrderListEntryBeside(list, node, target, offset) {
219
+ if (node === target)
220
+ return;
221
+ const existing = findNodeOrderListEntryIndex(list, node);
222
+ if (existing !== -1)
223
+ removeNodeOrderListEntryAtIndex(list, existing);
224
+ const targetIndex = findNodeOrderListEntryIndex(list, target);
225
+ if (targetIndex === -1)
226
+ return;
227
+ const sortKey = list.sortKeys[targetIndex];
228
+ const at = targetIndex + offset;
229
+ addNodeOrderListEntry(list, node, sortKey);
230
+ for (let i = list.entryCount - 1; i > at; i--) {
231
+ list.nodes[i] = list.nodes[i - 1];
232
+ list.sortKeys[i] = list.sortKeys[i - 1];
233
+ }
234
+ list.nodes[at] = node;
235
+ list.sortKeys[at] = sortKey;
236
+ }
237
+ function removeNodeOrderListEntryAtIndex(list, index) {
238
+ const last = list.entryCount - 1;
239
+ for (let i = index; i < last; i++) {
240
+ list.nodes[i] = list.nodes[i + 1];
241
+ list.sortKeys[i] = list.sortKeys[i + 1];
242
+ }
243
+ list.entryCount = last;
244
+ }
245
+ // Scratch reused across applyNodeOrderList calls so a per-frame apply allocates nothing. Cleared on
246
+ // every exit path, including before the order-changed signal fires, so a reentrant apply starts clean.
247
+ const _listIndex = new Map();
248
+ const _members = [];
249
+ const _slots = [];
250
+ //# sourceMappingURL=nodeOrderList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeOrderList.js","sourceRoot":"","sources":["../src/nodeOrderList.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/node",
3
- "version": "0.3.0-next.1595.4d49b41",
3
+ "version": "0.3.0-next.1665.6235922",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -36,12 +36,12 @@
36
36
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@flighthq/adjustments": "0.3.0-next.1595.4d49b41",
40
- "@flighthq/entity": "0.3.0-next.1595.4d49b41",
41
- "@flighthq/geometry": "0.3.0-next.1595.4d49b41",
42
- "@flighthq/materials": "0.3.0-next.1595.4d49b41",
43
- "@flighthq/signals": "0.3.0-next.1595.4d49b41",
44
- "@flighthq/types": "0.3.0-next.1595.4d49b41"
39
+ "@flighthq/adjustments": "0.3.0-next.1665.6235922",
40
+ "@flighthq/entity": "0.3.0-next.1665.6235922",
41
+ "@flighthq/geometry": "0.3.0-next.1665.6235922",
42
+ "@flighthq/materials": "0.3.0-next.1665.6235922",
43
+ "@flighthq/signals": "0.3.0-next.1665.6235922",
44
+ "@flighthq/types": "0.3.0-next.1665.6235922"
45
45
  },
46
46
  "devDependencies": {
47
47
  "typescript": "^5.3.0"
@@ -0,0 +1,617 @@
1
+ import { connectSignal } from '@flighthq/signals/contract';
2
+ import type { Node, NodeTraits } from '@flighthq/types/contract';
3
+ import { NodeKind } from '@flighthq/types/contract';
4
+
5
+ import { addNodeChild, removeNodeChild } from './hierarchy';
6
+ import { createNode, enableNodeSignals, getNodeRuntime } from './node';
7
+ import {
8
+ addNodeOrderListEntry,
9
+ applyNodeOrderList,
10
+ clearNodeOrderList,
11
+ createNodeOrderList,
12
+ disposeNodeOrderList,
13
+ forEachNodeOrderListEntry,
14
+ getNodeOrderListEntrySortKey,
15
+ hasNodeOrderListEntry,
16
+ removeNodeOrderListEntry,
17
+ setNodeOrderListEntry,
18
+ setNodeOrderListEntryAbove,
19
+ setNodeOrderListEntryBelow,
20
+ setNodeOrderListFromNodeChildren,
21
+ swapNodeOrderListEntries,
22
+ } from './nodeOrderList';
23
+ import { getNodeChildrenRevision } from './revision';
24
+
25
+ let container: Node<NodeTraits>;
26
+ let childA: Node<NodeTraits>;
27
+ let childB: Node<NodeTraits>;
28
+ let childC: Node<NodeTraits>;
29
+
30
+ beforeEach(() => {
31
+ container = createNode(NodeKind);
32
+ childA = createNode(NodeKind);
33
+ childB = createNode(NodeKind);
34
+ childC = createNode(NodeKind);
35
+ });
36
+
37
+ function getChildren(source: Node) {
38
+ return getNodeRuntime(source).children as Node[];
39
+ }
40
+
41
+ function attachAll() {
42
+ addNodeChild(container, childA);
43
+ addNodeChild(container, childB);
44
+ addNodeChild(container, childC);
45
+ }
46
+
47
+ describe('addNodeOrderListEntry', () => {
48
+ it('appends entries into the valid window', () => {
49
+ const list = createNodeOrderList();
50
+
51
+ addNodeOrderListEntry(list, childA, 5);
52
+ addNodeOrderListEntry(list, childB, 2);
53
+
54
+ expect(list.entryCount).toBe(2);
55
+ expect(list.nodes[0]).toBe(childA);
56
+ expect(list.sortKeys[0]).toBe(5);
57
+ expect(list.nodes[1]).toBe(childB);
58
+ expect(list.sortKeys[1]).toBe(2);
59
+ });
60
+
61
+ it('reuses capacity after a clear rather than growing the arrays', () => {
62
+ const list = createNodeOrderList();
63
+ addNodeOrderListEntry(list, childA, 1);
64
+ addNodeOrderListEntry(list, childB, 2);
65
+ clearNodeOrderList(list);
66
+
67
+ addNodeOrderListEntry(list, childC, 3);
68
+
69
+ expect(list.entryCount).toBe(1);
70
+ expect(list.nodes.length).toBe(2);
71
+ expect(list.nodes[0]).toBe(childC);
72
+ });
73
+
74
+ it('allows a node to be entered twice', () => {
75
+ const list = createNodeOrderList();
76
+
77
+ addNodeOrderListEntry(list, childA, 1);
78
+ addNodeOrderListEntry(list, childA, 2);
79
+
80
+ expect(list.entryCount).toBe(2);
81
+ });
82
+ });
83
+
84
+ describe('applyNodeOrderList', () => {
85
+ it('permutes members into ascending sort-key order', () => {
86
+ attachAll();
87
+ const list = createNodeOrderList();
88
+ addNodeOrderListEntry(list, childA, 30);
89
+ addNodeOrderListEntry(list, childB, 20);
90
+ addNodeOrderListEntry(list, childC, 10);
91
+
92
+ applyNodeOrderList(container, list);
93
+
94
+ expect(getChildren(container)).toEqual([childC, childB, childA]);
95
+ });
96
+
97
+ it('never moves a child the list does not name', () => {
98
+ const foreign = createNode(NodeKind);
99
+ addNodeChild(container, childA);
100
+ addNodeChild(container, foreign);
101
+ addNodeChild(container, childB);
102
+ const list = createNodeOrderList();
103
+ addNodeOrderListEntry(list, childA, 20);
104
+ addNodeOrderListEntry(list, childB, 10);
105
+
106
+ applyNodeOrderList(container, list);
107
+
108
+ // The members swap across the slots they held (0 and 2); the foreign child keeps slot 1, so it
109
+ // still sits between them rather than being compacted to one side.
110
+ expect(getChildren(container)).toEqual([childB, foreign, childA]);
111
+ });
112
+
113
+ it('ignores entries that are not children of the target', () => {
114
+ const stranger = createNode(NodeKind);
115
+ addNodeChild(container, childA);
116
+ addNodeChild(container, childB);
117
+ const list = createNodeOrderList();
118
+ addNodeOrderListEntry(list, childA, 30);
119
+ addNodeOrderListEntry(list, stranger, 20);
120
+ addNodeOrderListEntry(list, childB, 10);
121
+
122
+ applyNodeOrderList(container, list);
123
+
124
+ expect(getChildren(container)).toEqual([childB, childA]);
125
+ });
126
+
127
+ it('ignores entries attached to a different parent', () => {
128
+ const other = createNode(NodeKind);
129
+ addNodeChild(container, childA);
130
+ addNodeChild(container, childB);
131
+ addNodeChild(other, childC);
132
+ const list = createNodeOrderList();
133
+ addNodeOrderListEntry(list, childA, 30);
134
+ addNodeOrderListEntry(list, childC, 20);
135
+ addNodeOrderListEntry(list, childB, 10);
136
+
137
+ applyNodeOrderList(container, list);
138
+
139
+ expect(getChildren(container)).toEqual([childB, childA]);
140
+ expect(getChildren(other)).toEqual([childC]);
141
+ });
142
+
143
+ it('is a no-op once every member has been removed', () => {
144
+ const foreign = createNode(NodeKind);
145
+ addNodeChild(container, childA);
146
+ addNodeChild(container, foreign);
147
+ const list = createNodeOrderList();
148
+ addNodeOrderListEntry(list, childA, 20);
149
+ addNodeOrderListEntry(list, childB, 10);
150
+ removeNodeChild(container, childA);
151
+ const revision = getNodeChildrenRevision(container);
152
+
153
+ applyNodeOrderList(container, list);
154
+
155
+ expect(getChildren(container)).toEqual([foreign]);
156
+ expect(getNodeChildrenRevision(container)).toBe(revision);
157
+ });
158
+
159
+ it('sorts the survivors when only some members were removed', () => {
160
+ attachAll();
161
+ const list = createNodeOrderList();
162
+ addNodeOrderListEntry(list, childA, 30);
163
+ addNodeOrderListEntry(list, childB, 20);
164
+ addNodeOrderListEntry(list, childC, 10);
165
+ removeNodeChild(container, childB);
166
+
167
+ applyNodeOrderList(container, list);
168
+
169
+ expect(getChildren(container)).toEqual([childC, childA]);
170
+ });
171
+
172
+ it('breaks equal sort keys by the order the entries were added', () => {
173
+ addNodeChild(container, childC);
174
+ addNodeChild(container, childB);
175
+ addNodeChild(container, childA);
176
+ const list = createNodeOrderList();
177
+ addNodeOrderListEntry(list, childA, 7);
178
+ addNodeOrderListEntry(list, childB, 7);
179
+ addNodeOrderListEntry(list, childC, 7);
180
+
181
+ applyNodeOrderList(container, list);
182
+
183
+ expect(getChildren(container)).toEqual([childA, childB, childC]);
184
+ });
185
+
186
+ it('resolves a node entered twice to its last entry', () => {
187
+ addNodeChild(container, childA);
188
+ addNodeChild(container, childB);
189
+ const list = createNodeOrderList();
190
+ addNodeOrderListEntry(list, childA, 10);
191
+ addNodeOrderListEntry(list, childB, 20);
192
+ addNodeOrderListEntry(list, childA, 30);
193
+
194
+ applyNodeOrderList(container, list);
195
+
196
+ expect(getChildren(container)).toEqual([childB, childA]);
197
+ });
198
+
199
+ it('is idempotent', () => {
200
+ addNodeChild(container, childA);
201
+ addNodeChild(container, childB);
202
+ const list = createNodeOrderList();
203
+ addNodeOrderListEntry(list, childA, 20);
204
+ addNodeOrderListEntry(list, childB, 10);
205
+ applyNodeOrderList(container, list);
206
+ const revision = getNodeChildrenRevision(container);
207
+
208
+ applyNodeOrderList(container, list);
209
+
210
+ expect(getChildren(container)).toEqual([childB, childA]);
211
+ expect(getNodeChildrenRevision(container)).toBe(revision);
212
+ });
213
+
214
+ it('advances the children revision once for the whole permutation', () => {
215
+ attachAll();
216
+ const list = createNodeOrderList();
217
+ addNodeOrderListEntry(list, childA, 30);
218
+ addNodeOrderListEntry(list, childB, 20);
219
+ addNodeOrderListEntry(list, childC, 10);
220
+ const revision = getNodeChildrenRevision(container);
221
+
222
+ applyNodeOrderList(container, list);
223
+
224
+ expect(getNodeChildrenRevision(container)).toBe((revision + 1) >>> 0);
225
+ });
226
+
227
+ it('calls onChildrenOrderChanged on the parent once', () => {
228
+ attachAll();
229
+ const list = createNodeOrderList();
230
+ addNodeOrderListEntry(list, childA, 30);
231
+ addNodeOrderListEntry(list, childB, 20);
232
+ addNodeOrderListEntry(list, childC, 10);
233
+ let calls = 0;
234
+ connectSignal(enableNodeSignals(container).onChildrenOrderChanged, () => {
235
+ calls++;
236
+ });
237
+
238
+ applyNodeOrderList(container, list);
239
+
240
+ expect(calls).toBe(1);
241
+ });
242
+
243
+ it('does not signal when nothing moved', () => {
244
+ addNodeChild(container, childA);
245
+ addNodeChild(container, childB);
246
+ const list = createNodeOrderList();
247
+ addNodeOrderListEntry(list, childA, 10);
248
+ addNodeOrderListEntry(list, childB, 20);
249
+ let calls = 0;
250
+ connectSignal(enableNodeSignals(container).onChildrenOrderChanged, () => {
251
+ calls++;
252
+ });
253
+
254
+ applyNodeOrderList(container, list);
255
+
256
+ expect(calls).toBe(0);
257
+ });
258
+
259
+ it('leaves an empty list alone', () => {
260
+ addNodeChild(container, childA);
261
+ addNodeChild(container, childB);
262
+ const revision = getNodeChildrenRevision(container);
263
+
264
+ applyNodeOrderList(container, createNodeOrderList());
265
+
266
+ expect(getChildren(container)).toEqual([childA, childB]);
267
+ expect(getNodeChildrenRevision(container)).toBe(revision);
268
+ });
269
+ });
270
+
271
+ describe('clearNodeOrderList', () => {
272
+ it('empties the valid window but keeps capacity', () => {
273
+ const list = createNodeOrderList();
274
+ addNodeOrderListEntry(list, childA, 1);
275
+
276
+ clearNodeOrderList(list);
277
+
278
+ expect(list.entryCount).toBe(0);
279
+ expect(list.nodes.length).toBe(1);
280
+ });
281
+ });
282
+
283
+ describe('createNodeOrderList', () => {
284
+ it('creates an empty list', () => {
285
+ const list = createNodeOrderList();
286
+
287
+ expect(list.entryCount).toBe(0);
288
+ expect(list.nodes).toEqual([]);
289
+ expect(list.sortKeys).toEqual([]);
290
+ });
291
+ });
292
+
293
+ describe('disposeNodeOrderList', () => {
294
+ it('releases the node references clear deliberately retains', () => {
295
+ const list = createNodeOrderList();
296
+ addNodeOrderListEntry(list, childA, 1);
297
+ addNodeOrderListEntry(list, childB, 2);
298
+
299
+ disposeNodeOrderList(list);
300
+
301
+ expect(list.entryCount).toBe(0);
302
+ expect(list.nodes.length).toBe(0);
303
+ expect(list.sortKeys.length).toBe(0);
304
+ });
305
+
306
+ it('leaves the list usable', () => {
307
+ const list = createNodeOrderList();
308
+ addNodeOrderListEntry(list, childA, 1);
309
+ disposeNodeOrderList(list);
310
+
311
+ addNodeOrderListEntry(list, childB, 4);
312
+
313
+ expect(list.entryCount).toBe(1);
314
+ expect(getNodeOrderListEntrySortKey(list, childB)).toBe(4);
315
+ });
316
+ });
317
+
318
+ describe('forEachNodeOrderListEntry', () => {
319
+ it('visits every entry in entry order', () => {
320
+ const list = createNodeOrderList();
321
+ addNodeOrderListEntry(list, childA, 30);
322
+ addNodeOrderListEntry(list, childB, 10);
323
+ const seen: [Node, number, number][] = [];
324
+
325
+ forEachNodeOrderListEntry(list, (node, sortKey, index) => {
326
+ seen.push([node, sortKey, index]);
327
+ });
328
+
329
+ expect(seen).toEqual([
330
+ [childA, 30, 0],
331
+ [childB, 10, 1],
332
+ ]);
333
+ });
334
+
335
+ it('stops early when the callback returns false', () => {
336
+ const list = createNodeOrderList();
337
+ addNodeOrderListEntry(list, childA, 1);
338
+ addNodeOrderListEntry(list, childB, 2);
339
+ let visits = 0;
340
+
341
+ forEachNodeOrderListEntry(list, () => {
342
+ visits++;
343
+ return false;
344
+ });
345
+
346
+ expect(visits).toBe(1);
347
+ });
348
+
349
+ it('does not visit entries past the valid window', () => {
350
+ const list = createNodeOrderList();
351
+ addNodeOrderListEntry(list, childA, 1);
352
+ addNodeOrderListEntry(list, childB, 2);
353
+ clearNodeOrderList(list);
354
+ addNodeOrderListEntry(list, childC, 3);
355
+ let visits = 0;
356
+
357
+ forEachNodeOrderListEntry(list, () => {
358
+ visits++;
359
+ });
360
+
361
+ expect(visits).toBe(1);
362
+ });
363
+ });
364
+
365
+ describe('getNodeOrderListEntrySortKey', () => {
366
+ it('returns the sort key a node is entered with', () => {
367
+ const list = createNodeOrderList();
368
+ addNodeOrderListEntry(list, childA, -4);
369
+
370
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(-4);
371
+ });
372
+
373
+ it('returns null rather than -1 for a node with no entry', () => {
374
+ const list = createNodeOrderList();
375
+
376
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBeNull();
377
+ });
378
+
379
+ it('reports the winning entry when a node is entered twice', () => {
380
+ const list = createNodeOrderList();
381
+ addNodeOrderListEntry(list, childA, 1);
382
+ addNodeOrderListEntry(list, childA, 9);
383
+
384
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(9);
385
+ });
386
+ });
387
+
388
+ describe('hasNodeOrderListEntry', () => {
389
+ it('reports whether a node is entered', () => {
390
+ const list = createNodeOrderList();
391
+ addNodeOrderListEntry(list, childA, 1);
392
+
393
+ expect(hasNodeOrderListEntry(list, childA)).toBe(true);
394
+ expect(hasNodeOrderListEntry(list, childB)).toBe(false);
395
+ });
396
+
397
+ it('does not see entries past the valid window', () => {
398
+ const list = createNodeOrderList();
399
+ addNodeOrderListEntry(list, childA, 1);
400
+ clearNodeOrderList(list);
401
+
402
+ expect(hasNodeOrderListEntry(list, childA)).toBe(false);
403
+ });
404
+ });
405
+
406
+ describe('removeNodeOrderListEntry', () => {
407
+ it('removes the entry and reports that it did', () => {
408
+ const list = createNodeOrderList();
409
+ addNodeOrderListEntry(list, childA, 1);
410
+ addNodeOrderListEntry(list, childB, 2);
411
+
412
+ expect(removeNodeOrderListEntry(list, childA)).toBe(true);
413
+ expect(list.entryCount).toBe(1);
414
+ expect(hasNodeOrderListEntry(list, childA)).toBe(false);
415
+ expect(getNodeOrderListEntrySortKey(list, childB)).toBe(2);
416
+ });
417
+
418
+ it('reports false for a node with no entry', () => {
419
+ const list = createNodeOrderList();
420
+
421
+ expect(removeNodeOrderListEntry(list, childA)).toBe(false);
422
+ });
423
+
424
+ it('shifts the remaining entries down so tie order survives', () => {
425
+ attachAll();
426
+ const list = createNodeOrderList();
427
+ addNodeOrderListEntry(list, childA, 7);
428
+ addNodeOrderListEntry(list, childC, 7);
429
+ addNodeOrderListEntry(list, childB, 7);
430
+ removeNodeOrderListEntry(list, childA);
431
+
432
+ applyNodeOrderList(container, list);
433
+
434
+ // A keeps slot 0 — only its entry was removed, not the child. C was entered before B and stays
435
+ // before it; a swap-with-last removal would have put B first and left the children untouched.
436
+ expect(getChildren(container)).toEqual([childA, childC, childB]);
437
+ });
438
+ });
439
+
440
+ describe('setNodeOrderListEntry', () => {
441
+ it('enters a node that has no entry', () => {
442
+ const list = createNodeOrderList();
443
+
444
+ setNodeOrderListEntry(list, childA, 3);
445
+
446
+ expect(list.entryCount).toBe(1);
447
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(3);
448
+ });
449
+
450
+ it('re-keys in place rather than adding a second entry', () => {
451
+ const list = createNodeOrderList();
452
+ setNodeOrderListEntry(list, childA, 3);
453
+
454
+ setNodeOrderListEntry(list, childA, 8);
455
+
456
+ expect(list.entryCount).toBe(1);
457
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(8);
458
+ });
459
+ });
460
+
461
+ describe('setNodeOrderListEntryAbove', () => {
462
+ it('places a node immediately above the target', () => {
463
+ attachAll();
464
+ const list = createNodeOrderList();
465
+ setNodeOrderListFromNodeChildren(list, container);
466
+
467
+ setNodeOrderListEntryAbove(list, childA, childC);
468
+ applyNodeOrderList(container, list);
469
+
470
+ expect(getChildren(container)).toEqual([childB, childC, childA]);
471
+ });
472
+
473
+ it('places between neighbours whose keys leave no gap', () => {
474
+ attachAll();
475
+ const list = createNodeOrderList();
476
+ addNodeOrderListEntry(list, childB, 5);
477
+ addNodeOrderListEntry(list, childC, 6);
478
+
479
+ setNodeOrderListEntryAbove(list, childA, childB);
480
+ applyNodeOrderList(container, list);
481
+
482
+ // No midpoint exists between 5 and 6, so bisection could not express this; the equal-key plus
483
+ // entry-position rule can.
484
+ expect(getChildren(container)).toEqual([childB, childA, childC]);
485
+ });
486
+
487
+ it('moves a node that is already entered rather than duplicating it', () => {
488
+ const list = createNodeOrderList();
489
+ addNodeOrderListEntry(list, childA, 1);
490
+ addNodeOrderListEntry(list, childC, 9);
491
+
492
+ setNodeOrderListEntryAbove(list, childA, childC);
493
+
494
+ expect(list.entryCount).toBe(2);
495
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(9);
496
+ });
497
+
498
+ it('does nothing when the target has no entry', () => {
499
+ const list = createNodeOrderList();
500
+
501
+ setNodeOrderListEntryAbove(list, childA, childC);
502
+
503
+ expect(list.entryCount).toBe(0);
504
+ });
505
+
506
+ it('does nothing when the node is its own target', () => {
507
+ const list = createNodeOrderList();
508
+ addNodeOrderListEntry(list, childA, 4);
509
+
510
+ setNodeOrderListEntryAbove(list, childA, childA);
511
+
512
+ expect(list.entryCount).toBe(1);
513
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(4);
514
+ });
515
+ });
516
+
517
+ describe('setNodeOrderListEntryBelow', () => {
518
+ it('places a node immediately below the target', () => {
519
+ attachAll();
520
+ const list = createNodeOrderList();
521
+ setNodeOrderListFromNodeChildren(list, container);
522
+
523
+ setNodeOrderListEntryBelow(list, childA, childC);
524
+ applyNodeOrderList(container, list);
525
+
526
+ expect(getChildren(container)).toEqual([childB, childA, childC]);
527
+ });
528
+
529
+ it('places between neighbours whose keys leave no gap', () => {
530
+ attachAll();
531
+ const list = createNodeOrderList();
532
+ addNodeOrderListEntry(list, childB, 5);
533
+ addNodeOrderListEntry(list, childC, 6);
534
+
535
+ setNodeOrderListEntryBelow(list, childA, childC);
536
+ applyNodeOrderList(container, list);
537
+
538
+ expect(getChildren(container)).toEqual([childB, childA, childC]);
539
+ });
540
+
541
+ it('does nothing when the target has no entry', () => {
542
+ const list = createNodeOrderList();
543
+
544
+ setNodeOrderListEntryBelow(list, childA, childC);
545
+
546
+ expect(list.entryCount).toBe(0);
547
+ });
548
+ });
549
+
550
+ describe('setNodeOrderListFromNodeChildren', () => {
551
+ it('enters every child at its own index', () => {
552
+ attachAll();
553
+ const list = createNodeOrderList();
554
+
555
+ setNodeOrderListFromNodeChildren(list, container);
556
+
557
+ expect(list.entryCount).toBe(3);
558
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(0);
559
+ expect(getNodeOrderListEntrySortKey(list, childB)).toBe(1);
560
+ expect(getNodeOrderListEntrySortKey(list, childC)).toBe(2);
561
+ });
562
+
563
+ it('round-trips through apply without moving anything', () => {
564
+ attachAll();
565
+ const list = createNodeOrderList();
566
+ setNodeOrderListFromNodeChildren(list, container);
567
+ const revision = getNodeChildrenRevision(container);
568
+
569
+ applyNodeOrderList(container, list);
570
+
571
+ expect(getChildren(container)).toEqual([childA, childB, childC]);
572
+ expect(getNodeChildrenRevision(container)).toBe(revision);
573
+ });
574
+
575
+ it('discards any previous contents', () => {
576
+ const stranger = createNode(NodeKind);
577
+ addNodeChild(container, childA);
578
+ const list = createNodeOrderList();
579
+ addNodeOrderListEntry(list, stranger, 99);
580
+
581
+ setNodeOrderListFromNodeChildren(list, container);
582
+
583
+ expect(list.entryCount).toBe(1);
584
+ expect(hasNodeOrderListEntry(list, stranger)).toBe(false);
585
+ });
586
+
587
+ it('empties the list for a node with no children', () => {
588
+ const list = createNodeOrderList();
589
+ addNodeOrderListEntry(list, childA, 1);
590
+
591
+ setNodeOrderListFromNodeChildren(list, childB);
592
+
593
+ expect(list.entryCount).toBe(0);
594
+ });
595
+ });
596
+
597
+ describe('swapNodeOrderListEntries', () => {
598
+ it('exchanges the sort keys of two entered nodes', () => {
599
+ attachAll();
600
+ const list = createNodeOrderList();
601
+ setNodeOrderListFromNodeChildren(list, container);
602
+
603
+ swapNodeOrderListEntries(list, childA, childC);
604
+ applyNodeOrderList(container, list);
605
+
606
+ expect(getChildren(container)).toEqual([childC, childB, childA]);
607
+ });
608
+
609
+ it('does nothing unless both nodes are entered', () => {
610
+ const list = createNodeOrderList();
611
+ addNodeOrderListEntry(list, childA, 1);
612
+
613
+ swapNodeOrderListEntries(list, childA, childB);
614
+
615
+ expect(getNodeOrderListEntrySortKey(list, childA)).toBe(1);
616
+ });
617
+ });