@velarscript/web 0.12.0 → 0.13.0
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.
- package/README.md +2 -2
- package/dist/analyzer.d.ts +164 -23
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +1254 -133
- package/dist/analyzer.js.map +1 -1
- package/dist/ast.d.ts +11 -0
- package/dist/ast.d.ts.map +1 -1
- package/dist/ast.js +22 -0
- package/dist/ast.js.map +1 -1
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +69 -44
- package/dist/compiler.js.map +1 -1
- package/dist/css-string.d.ts +32 -0
- package/dist/css-string.d.ts.map +1 -0
- package/dist/css-string.js +66 -0
- package/dist/css-string.js.map +1 -0
- package/dist/css-tokens.d.ts +16 -0
- package/dist/css-tokens.d.ts.map +1 -1
- package/dist/css-tokens.js +84 -0
- package/dist/css-tokens.js.map +1 -1
- package/dist/elements.d.ts +55 -0
- package/dist/elements.d.ts.map +1 -1
- package/dist/elements.js +152 -0
- package/dist/elements.js.map +1 -1
- package/dist/emitter.d.ts +10 -0
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +588 -159
- package/dist/emitter.js.map +1 -1
- package/dist/keyframes.d.ts +17 -0
- package/dist/keyframes.d.ts.map +1 -1
- package/dist/keyframes.js +28 -9
- package/dist/keyframes.js.map +1 -1
- package/dist/lexer.d.ts +21 -7
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +32 -12
- package/dist/lexer.js.map +1 -1
- package/dist/look-static.d.ts.map +1 -1
- package/dist/look-static.js +120 -20
- package/dist/look-static.js.map +1 -1
- package/dist/look.d.ts +15 -0
- package/dist/look.d.ts.map +1 -1
- package/dist/look.js +7 -2
- package/dist/look.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +15 -20
- package/dist/parser.js.map +1 -1
- package/dist/runtime-foundation.d.ts.map +1 -1
- package/dist/runtime-foundation.js +321 -70
- package/dist/runtime-foundation.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +320 -179
- package/dist/runtime.js.map +1 -1
- package/dist/stable-order.d.ts +16 -0
- package/dist/stable-order.d.ts.map +1 -0
- package/dist/stable-order.js +18 -0
- package/dist/stable-order.js.map +1 -0
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -16
- package/dist/types.js.map +1 -1
- package/dist/websocket-runtime.d.ts.map +1 -1
- package/dist/websocket-runtime.js +9 -5
- package/dist/websocket-runtime.js.map +1 -1
- package/dist/worker-runtime.d.ts.map +1 -1
- package/dist/worker-runtime.js +9 -7
- package/dist/worker-runtime.js.map +1 -1
- package/package.json +2 -2
|
@@ -432,6 +432,8 @@ const __velarGraphNativeWeakMap = globalThis.WeakMap;
|
|
|
432
432
|
const __velarGraphNativeProxy = globalThis.Proxy;
|
|
433
433
|
const __velarGraphReflectApply = Object.getOwnPropertyDescriptor(Reflect, "apply")?.value;
|
|
434
434
|
const __velarGraphArrayIsArray = Object.getOwnPropertyDescriptor(Array, "isArray")?.value;
|
|
435
|
+
const __velarGraphArrayPrototype = Object.getOwnPropertyDescriptor(__velarGraphNativeArray, "prototype")?.value;
|
|
436
|
+
const __velarGraphArraySort = __velarGraphArrayPrototype && Object.getOwnPropertyDescriptor(__velarGraphArrayPrototype, "sort")?.value;
|
|
435
437
|
const __velarGraphObjectIs = Object.getOwnPropertyDescriptor(Object, "is")?.value;
|
|
436
438
|
const __velarGraphObjectFreeze = Object.getOwnPropertyDescriptor(Object, "freeze")?.value;
|
|
437
439
|
const __velarGraphObjectDefineProperty = Object.getOwnPropertyDescriptor(Object, "defineProperty")?.value;
|
|
@@ -509,6 +511,7 @@ function __velarGraphWeakMapRead(value, key) { return __velarGraphApply(__velarG
|
|
|
509
511
|
function __velarGraphWeakMapWrite(value, key, item) { return __velarGraphApply(__velarGraphWeakMapSet, value, [key, item], "WeakMap.set"); }
|
|
510
512
|
function __velarGraphWeakMapRemove(value, key) { return __velarGraphApply(__velarGraphWeakMapDelete, value, [key], "WeakMap.delete"); }
|
|
511
513
|
function __velarGraphIsList(value) { return __velarGraphApply(__velarGraphArrayIsArray, __velarGraphNativeArray, [value], "Array.isArray"); }
|
|
514
|
+
function __velarGraphOrder(value, compare) { return __velarGraphApply(__velarGraphArraySort, value, [compare], "Array.sort"); }
|
|
512
515
|
function __velarGraphSame(left, right) { return __velarGraphApply(__velarGraphObjectIs, __velarGraphNativeObject, [left, right], "Object.is"); }
|
|
513
516
|
function __velarGraphFreeze(value) { return __velarGraphApply(__velarGraphObjectFreeze, __velarGraphNativeObject, [value], "Object.freeze"); }
|
|
514
517
|
function __velarGraphDefine(value, key, descriptor) { return __velarGraphApply(__velarGraphObjectDefineProperty, __velarGraphNativeObject, [value, key, descriptor], "Object.defineProperty"); }
|
|
@@ -630,6 +633,239 @@ function __velarReportOptions(value) {
|
|
|
630
633
|
return output;
|
|
631
634
|
}
|
|
632
635
|
|
|
636
|
+
// D90 R21: the number stamped on each observer when it is created, and the
|
|
637
|
+
// order the flush runs the watch tier in -- execution order is the order the
|
|
638
|
+
// author wrote the watches, and "wrote" spans more than one file: watches of
|
|
639
|
+
// one module register as that module initializes, instances of one component
|
|
640
|
+
// register as they mount, and modules register in the order the import graph
|
|
641
|
+
// initializes them. Every one of those is registration order, so one counter
|
|
642
|
+
// answers all three.
|
|
643
|
+
//
|
|
644
|
+
// It has to be application-wide, not per module. Each emitted module carries
|
|
645
|
+
// its own copy of this runtime, so a module-scope counter would restart at zero
|
|
646
|
+
// in the second module and the two modules' watches would compare equal. The
|
|
647
|
+
// counter therefore lives on one global slot every copy reads, the same way the
|
|
648
|
+
// runtime registry itself does.
|
|
649
|
+
const __velarObserverSequenceKey = Symbol.for("velar.web.observer.sequence.v1");
|
|
650
|
+
const __velarObserverSequenceCell = (() => {
|
|
651
|
+
const descriptor = __velarGraphOwnDescriptor(globalThis, __velarObserverSequenceKey);
|
|
652
|
+
if (descriptor) {
|
|
653
|
+
if (!("value" in descriptor) || descriptor.enumerable || descriptor.configurable || descriptor.writable
|
|
654
|
+
|| !__velarGraphIsList(descriptor.value)) {
|
|
655
|
+
throw new TypeError("VelarScript Web observer sequence ownership is invalid");
|
|
656
|
+
}
|
|
657
|
+
return descriptor.value;
|
|
658
|
+
}
|
|
659
|
+
const cell = [0];
|
|
660
|
+
__velarGraphDefine(globalThis, __velarObserverSequenceKey, {
|
|
661
|
+
value: cell,
|
|
662
|
+
enumerable: false,
|
|
663
|
+
configurable: false,
|
|
664
|
+
writable: false,
|
|
665
|
+
});
|
|
666
|
+
return cell;
|
|
667
|
+
})();
|
|
668
|
+
|
|
669
|
+
function __velarNextObserverSequence() {
|
|
670
|
+
__velarObserverSequenceCell[0] += 1;
|
|
671
|
+
return __velarObserverSequenceCell[0];
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// The identity a flush stamps its run counts with, carried by an overrun into
|
|
675
|
+
// the flush it schedules and consumed by the first flush that starts.
|
|
676
|
+
let __velarOverflowToken = null;
|
|
677
|
+
|
|
678
|
+
// The three observers that have run most in the settle running now, kept as
|
|
679
|
+
// the run counts are stamped rather than reconstructed afterwards: the queue at
|
|
680
|
+
// the moment the budget runs out holds only whichever half of a cycle has not
|
|
681
|
+
// just run, so it cannot name the ring on its own. An observer that has run
|
|
682
|
+
// once is not a candidate, which is every observer of an ordinary flush.
|
|
683
|
+
const __velarFlushLeaders = [];
|
|
684
|
+
|
|
685
|
+
function __velarFlushLead(observer) {
|
|
686
|
+
let kept = 0;
|
|
687
|
+
for (let index = 0; index < __velarFlushLeaders.length; index += 1) {
|
|
688
|
+
if (__velarFlushLeaders[index] === observer) continue;
|
|
689
|
+
__velarFlushLeaders[kept] = __velarFlushLeaders[index];
|
|
690
|
+
kept += 1;
|
|
691
|
+
}
|
|
692
|
+
__velarFlushLeaders.length = kept;
|
|
693
|
+
let position = kept;
|
|
694
|
+
while (position > 0 && __velarFlushLeaders[position - 1].flushRuns < observer.flushRuns) {
|
|
695
|
+
__velarFlushLeaders[position] = __velarFlushLeaders[position - 1];
|
|
696
|
+
position -= 1;
|
|
697
|
+
}
|
|
698
|
+
__velarFlushLeaders[position] = observer;
|
|
699
|
+
if (__velarFlushLeaders.length > 3) __velarFlushLeaders.length = 3;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// D90 R21: compile time no longer refuses two watches that write one state, so
|
|
703
|
+
// this budget is the only gate left against a mutual-write cycle -- and a
|
|
704
|
+
// report that names nobody hands the author a number with no line to go to.
|
|
705
|
+
// The observers that ran most in this flush chain are the cycle; flushRuns
|
|
706
|
+
// already counts exactly that, so the highest few are named. A watch's label is
|
|
707
|
+
// its subject as the author spelled it, which in a write cycle is also the
|
|
708
|
+
// state each watch is reacting to, and the scope it was registered in supplies
|
|
709
|
+
// the component the report has always had a field for.
|
|
710
|
+
//
|
|
711
|
+
// Nothing here asks who wrote what. That question is gone from the language,
|
|
712
|
+
// and answering it would need the write frames R21 deleted.
|
|
713
|
+
function __velarFlushRunaway(stalled, token) {
|
|
714
|
+
const ranked = [];
|
|
715
|
+
const seen = __velarGraphCreateSet();
|
|
716
|
+
const consider = (observer) => {
|
|
717
|
+
if (observer.flushToken !== token || __velarGraphSetContains(seen, observer)) return;
|
|
718
|
+
__velarGraphSetInsert(seen, observer);
|
|
719
|
+
ranked[ranked.length] = observer;
|
|
720
|
+
};
|
|
721
|
+
// A cycle alternates, so the queue at the instant the budget ran out holds
|
|
722
|
+
// only the half of the ring that has not just run. The leaders carry the
|
|
723
|
+
// other half.
|
|
724
|
+
for (let index = 0; index < __velarFlushLeaders.length; index += 1) consider(__velarFlushLeaders[index]);
|
|
725
|
+
for (let index = 0; index < stalled.length; index += 1) consider(stalled[index]);
|
|
726
|
+
__velarGraphOrder(ranked, (left, right) => right.flushRuns - left.flushRuns);
|
|
727
|
+
const limit = ranked.length < 3 ? ranked.length : 3;
|
|
728
|
+
let detail = "";
|
|
729
|
+
let component = "";
|
|
730
|
+
for (let index = 0; index < limit; index += 1) {
|
|
731
|
+
const observer = ranked[index];
|
|
732
|
+
const named = observer.mode === "watch" && typeof observer.label === "string" && observer.label !== ""
|
|
733
|
+
? "the watch on '" + observer.label + "'"
|
|
734
|
+
: "a " + observer.mode + " observer";
|
|
735
|
+
detail += (detail === "" ? "Ran most in this flush: " : ", ") + named
|
|
736
|
+
+ " (" + observer.flushRuns + (observer.flushRuns === 1 ? " run)" : " runs)");
|
|
737
|
+
if (component === "" && typeof observer.component === "string") component = observer.component;
|
|
738
|
+
}
|
|
739
|
+
return { detail, component };
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function __velarScheduleFlush() {
|
|
743
|
+
if (__velarRuntime.flushPending) return;
|
|
744
|
+
__velarRuntime.flushPending = true;
|
|
745
|
+
__velarEnqueue(__velarFlush);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// Only the observers that actually re-entered the queue during the overrun
|
|
749
|
+
// belong to the runaway cycle. An observer queued once by an unrelated write
|
|
750
|
+
// in the same turn is innocent, and stopping it is irreversible, so it is
|
|
751
|
+
// put back for the next microtask instead.
|
|
752
|
+
//
|
|
753
|
+
// Every overrun must still remove something, or the requeue turns the
|
|
754
|
+
// microtask chain into the freeze the budget exists to end: a cycle spread
|
|
755
|
+
// across more observers than the budget can run four times over re-enters
|
|
756
|
+
// none of them four times, so a fixed threshold of four stops nobody and the
|
|
757
|
+
// next flush repeats it forever. Two rules make the progress unconditional.
|
|
758
|
+
// The threshold falls to the highest run count actually present, so any
|
|
759
|
+
// queued observer this flush chain has already run is stopped; and the token
|
|
760
|
+
// is carried into the flush the overrun schedules, so run counts accumulate
|
|
761
|
+
// across the chain and the observers the chain has not reached yet are a
|
|
762
|
+
// pool that only shrinks.
|
|
763
|
+
function __velarFlushOverflow(token) {
|
|
764
|
+
const stalled = [];
|
|
765
|
+
for (const observer of __velarGraphSetItems(__velarRuntime.domQueue)) stalled[stalled.length] = observer;
|
|
766
|
+
for (const observer of __velarGraphSetItems(__velarRuntime.watchQueue)) stalled[stalled.length] = observer;
|
|
767
|
+
__velarGraphSetEmpty(__velarRuntime.domQueue);
|
|
768
|
+
__velarGraphSetEmpty(__velarRuntime.watchQueue);
|
|
769
|
+
let threshold = 0;
|
|
770
|
+
for (let index = 0; index < stalled.length; index += 1) {
|
|
771
|
+
const observer = stalled[index];
|
|
772
|
+
if (observer.flushToken === token && observer.flushRuns > threshold) threshold = observer.flushRuns;
|
|
773
|
+
}
|
|
774
|
+
if (threshold > 4) threshold = 4;
|
|
775
|
+
let requeued = false;
|
|
776
|
+
for (let index = 0; index < stalled.length; index += 1) {
|
|
777
|
+
const observer = stalled[index];
|
|
778
|
+
if (threshold > 0 && observer.flushToken === token && observer.flushRuns >= threshold) {
|
|
779
|
+
if (typeof observer.stop === "function") observer.stop();
|
|
780
|
+
else observer.stopped = true;
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
if (observer.stopped) continue;
|
|
784
|
+
__velarGraphSetInsert(observer.mode === "watch" ? __velarRuntime.watchQueue : __velarRuntime.domQueue, observer);
|
|
785
|
+
requeued = true;
|
|
786
|
+
}
|
|
787
|
+
const runaway = __velarFlushRunaway(stalled, token);
|
|
788
|
+
__velarRuntime.report(new RangeError("Reactive updates cannot run more than 100000 observers in one flush"),
|
|
789
|
+
{ phase: "update", detail: runaway.detail, component: runaway.component, unhandled: true });
|
|
790
|
+
if (requeued) {
|
|
791
|
+
__velarOverflowToken = token;
|
|
792
|
+
__velarScheduleFlush();
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// The one entry point: the microtask __velarScheduleFlush enqueues, and the
|
|
797
|
+
// synchronous drain the emitted tick() performs. It used to open and close D90
|
|
798
|
+
// R1-a-scope's flush-scoped writer registry around the settle; R21 deleted the
|
|
799
|
+
// registry with the referee that read it, so the name is all that remains and
|
|
800
|
+
// it remains because __velarEnqueue and tick() both hold it.
|
|
801
|
+
function __velarFlush() {
|
|
802
|
+
__velarFlushSettle();
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// Glitch-free order: every derived value and every watch settles to a fixed
|
|
806
|
+
// point before a single DOM node is written, so no watch and no rendered
|
|
807
|
+
// position can read a half-updated world and no corrective watch can push an
|
|
808
|
+
// invalid value through the DOM first. That is D90 R1 and it is unchanged.
|
|
809
|
+
//
|
|
810
|
+
// D90 R21 changed the other axis. Within the settle the watches run in
|
|
811
|
+
// registration order -- source order in a module, mount order across instances
|
|
812
|
+
// of one component, module-initialization order across modules -- and a watch
|
|
813
|
+
// that writes state is not promoted ahead of one that only observes. Whoever is
|
|
814
|
+
// written first runs first, two watches writing one state both take effect in
|
|
815
|
+
// that order, and a later write that clobbers an earlier one is the author's.
|
|
816
|
+
//
|
|
817
|
+
// Queue insertion order is not registration order and cannot stand in for it:
|
|
818
|
+
// two watches on two different states, both dirtied by one action, enter the
|
|
819
|
+
// queue in the order the action wrote the states. So each pass takes the queue
|
|
820
|
+
// as it stands and runs it by sequence number. Watches queued by this pass are
|
|
821
|
+
// picked up by the next one, in their own order.
|
|
822
|
+
function __velarFlushSettle() {
|
|
823
|
+
__velarRuntime.flushPending = false;
|
|
824
|
+
const token = __velarOverflowToken === null ? {} : __velarOverflowToken;
|
|
825
|
+
__velarOverflowToken = null;
|
|
826
|
+
__velarFlushLeaders.length = 0;
|
|
827
|
+
let budget = 100000;
|
|
828
|
+
const step = (observer) => {
|
|
829
|
+
__velarGraphSetRemove(observer.mode === "watch" ? __velarRuntime.watchQueue : __velarRuntime.domQueue, observer);
|
|
830
|
+
if (observer.flushToken === token) observer.flushRuns += 1;
|
|
831
|
+
else { observer.flushToken = token; observer.flushRuns = 1; }
|
|
832
|
+
if (observer.flushRuns > 1) __velarFlushLead(observer);
|
|
833
|
+
observer.run();
|
|
834
|
+
};
|
|
835
|
+
while (__velarGraphSetCount(__velarRuntime.domQueue) || __velarGraphSetCount(__velarRuntime.watchQueue)) {
|
|
836
|
+
while (true) {
|
|
837
|
+
let ran = false;
|
|
838
|
+
for (const observer of __velarGraphSetItems(__velarRuntime.domQueue)) {
|
|
839
|
+
if (observer.mode !== "computed") continue;
|
|
840
|
+
if ((budget -= 1) < 0) { __velarFlushOverflow(token); return; }
|
|
841
|
+
step(observer);
|
|
842
|
+
ran = true;
|
|
843
|
+
}
|
|
844
|
+
if (ran) continue;
|
|
845
|
+
const pending = [];
|
|
846
|
+
for (const observer of __velarGraphSetItems(__velarRuntime.watchQueue)) pending[pending.length] = observer;
|
|
847
|
+
__velarGraphOrder(pending, (left, right) => left.sequence - right.sequence);
|
|
848
|
+
for (let index = 0; index < pending.length; index += 1) {
|
|
849
|
+
const observer = pending[index];
|
|
850
|
+
// A watch this pass already re-ran or stopped is no longer queued; the
|
|
851
|
+
// snapshot is a plan, and the queue is what says whether it still owes
|
|
852
|
+
// a run.
|
|
853
|
+
if (observer.stopped || !__velarGraphSetContains(__velarRuntime.watchQueue, observer)) continue;
|
|
854
|
+
if ((budget -= 1) < 0) { __velarFlushOverflow(token); return; }
|
|
855
|
+
step(observer);
|
|
856
|
+
ran = true;
|
|
857
|
+
}
|
|
858
|
+
if (!ran) break;
|
|
859
|
+
}
|
|
860
|
+
for (const observer of __velarGraphSetItems(__velarRuntime.domQueue)) {
|
|
861
|
+
if (observer.mode === "computed") break;
|
|
862
|
+
if ((budget -= 1) < 0) { __velarFlushOverflow(token); return; }
|
|
863
|
+
step(observer);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
if (__velarGraphSetCount(__velarRuntime.domQueue) || __velarGraphSetCount(__velarRuntime.watchQueue)) __velarScheduleFlush();
|
|
867
|
+
}
|
|
868
|
+
|
|
633
869
|
function __velarCreateRuntime() {
|
|
634
870
|
const runtime = Object.create(null);
|
|
635
871
|
const domQueue = Object.freeze(__velarGraphCreateSet());
|
|
@@ -756,14 +992,23 @@ function __velarCreateRuntime() {
|
|
|
756
992
|
};
|
|
757
993
|
const link = (child, parent) => {
|
|
758
994
|
if (child === null || (typeof child !== "object" && typeof child !== "function")) return;
|
|
759
|
-
linkOwner(toRaw(child), parent);
|
|
995
|
+
linkOwner(toRaw(child), parent, true);
|
|
760
996
|
};
|
|
761
|
-
|
|
997
|
+
// 'structural' separates a slot being filled from a slot merely being read.
|
|
998
|
+
// A read proves the child is in the parent right now; only a write adds an
|
|
999
|
+
// occurrence, and only a write can create the duplicate the running count
|
|
1000
|
+
// cannot see for itself.
|
|
1001
|
+
const linkOwner = (child, parent, structural = false) => {
|
|
762
1002
|
parent = toRaw(parent);
|
|
763
1003
|
if (parent === null || (typeof parent !== "object" && typeof parent !== "function") || child === parent) return;
|
|
764
1004
|
let owners = __velarGraphWeakMapRead(parents, child);
|
|
765
1005
|
if (!owners) { owners = __velarGraphCreateSet(); __velarGraphWeakMapWrite(parents, child, owners); }
|
|
1006
|
+
const known = __velarGraphSetContains(owners, parent);
|
|
766
1007
|
__velarGraphSetInsert(owners, parent);
|
|
1008
|
+
const counts = __velarGraphWeakMapRead(containment, parent);
|
|
1009
|
+
if (!counts) return;
|
|
1010
|
+
if (structural && known) { __velarGraphWeakMapRemove(containment, parent); return; }
|
|
1011
|
+
if ((__velarGraphMapRead(counts, child) ?? 0) < 1) __velarGraphMapWrite(counts, child, 1);
|
|
767
1012
|
};
|
|
768
1013
|
// Removing the last owner of a value detaches everything only that value
|
|
769
1014
|
// owned. Without the cascade, replacing a state root leaves every surviving
|
|
@@ -850,43 +1095,74 @@ function __velarCreateRuntime() {
|
|
|
850
1095
|
if (value !== null && (typeof value === "object" || typeof value === "function")) visit(value);
|
|
851
1096
|
}
|
|
852
1097
|
};
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
1098
|
+
// Containment used to be re-derived by scanning the whole container on every
|
|
1099
|
+
// element write, which made one assignment into a rendered List cost O(list
|
|
1100
|
+
// length). The occurrence index answers the same question -- does the parent
|
|
1101
|
+
// still reference this child anywhere? -- in constant time: it is built once
|
|
1102
|
+
// from the container's real contents and then maintained by the same link and
|
|
1103
|
+
// release calls that change them.
|
|
1104
|
+
const containment = __velarGraphCreateWeakMap();
|
|
1105
|
+
const countOccurrence = (counts, value) => {
|
|
1106
|
+
value = toRaw(value);
|
|
1107
|
+
if (value === null || (typeof value !== "object" && typeof value !== "function")) return;
|
|
1108
|
+
__velarGraphMapWrite(counts, value, (__velarGraphMapRead(counts, value) ?? 0) + 1);
|
|
1109
|
+
};
|
|
1110
|
+
// Mirrors exactly what the old scan looked at, Map keys included as owned
|
|
1111
|
+
// values are, so the index cannot answer a question the scan answered
|
|
1112
|
+
// differently.
|
|
1113
|
+
const buildContainment = (parent) => {
|
|
1114
|
+
const counts = __velarGraphCreateMap();
|
|
856
1115
|
if (__velarGraphIsList(parent)) {
|
|
857
|
-
for (let index = 0; index < parent.length; index += 1)
|
|
858
|
-
|
|
859
|
-
}
|
|
860
|
-
return false;
|
|
1116
|
+
for (let index = 0; index < parent.length; index += 1) countOccurrence(counts, __velarGraphOwnDescriptor(parent, index)?.value);
|
|
1117
|
+
return counts;
|
|
861
1118
|
}
|
|
862
1119
|
const brand = collectionBrand(parent);
|
|
863
1120
|
if (brand === 1) {
|
|
864
|
-
for (const value of __velarGraphMapItems(parent))
|
|
865
|
-
return
|
|
1121
|
+
for (const value of __velarGraphMapItems(parent)) countOccurrence(counts, value);
|
|
1122
|
+
return counts;
|
|
866
1123
|
}
|
|
867
1124
|
if (brand === 2) {
|
|
868
|
-
for (const value of __velarGraphSetItems(parent))
|
|
869
|
-
return
|
|
1125
|
+
for (const value of __velarGraphSetItems(parent)) countOccurrence(counts, value);
|
|
1126
|
+
return counts;
|
|
870
1127
|
}
|
|
871
|
-
if (!parent || typeof parent !== "object") return
|
|
1128
|
+
if (!parent || typeof parent !== "object") return counts;
|
|
872
1129
|
for (const name of __velarGraphOwnNames(parent)) {
|
|
873
1130
|
const descriptor = __velarGraphOwnDescriptor(parent, name);
|
|
874
|
-
if (descriptor && "value" in descriptor
|
|
1131
|
+
if (descriptor && "value" in descriptor) countOccurrence(counts, descriptor.value);
|
|
875
1132
|
}
|
|
876
|
-
return
|
|
1133
|
+
return counts;
|
|
877
1134
|
};
|
|
878
1135
|
// The one guard every detach path shares: a primitive was never linked, and
|
|
879
1136
|
// an object with no owners has nothing to release, so neither may reach the
|
|
880
|
-
//
|
|
1137
|
+
// containment bookkeeping.
|
|
881
1138
|
const releaseChild = (parent, child) => {
|
|
882
1139
|
if (child === null || (typeof child !== "object" && typeof child !== "function")
|
|
883
1140
|
|| !__velarGraphWeakMapContains(parents, child)) return;
|
|
884
|
-
|
|
1141
|
+
parent = toRaw(parent);
|
|
1142
|
+
if (parent === null || (typeof parent !== "object" && typeof parent !== "function")) return;
|
|
1143
|
+
child = toRaw(child);
|
|
1144
|
+
// A freshly built index already reflects the slot that was just cleared;
|
|
1145
|
+
// a maintained one still counts it, so only that one takes the decrement.
|
|
1146
|
+
let counts = __velarGraphWeakMapRead(containment, parent);
|
|
1147
|
+
let remaining;
|
|
1148
|
+
if (counts) remaining = (__velarGraphMapRead(counts, child) ?? 0) - 1;
|
|
1149
|
+
else {
|
|
1150
|
+
counts = buildContainment(parent);
|
|
1151
|
+
__velarGraphWeakMapWrite(containment, parent, counts);
|
|
1152
|
+
remaining = __velarGraphMapRead(counts, child) ?? 0;
|
|
1153
|
+
}
|
|
1154
|
+
if (remaining > 0) { __velarGraphMapWrite(counts, child, remaining); return; }
|
|
1155
|
+
__velarGraphMapRemove(counts, child);
|
|
1156
|
+
unlink(child, parent);
|
|
885
1157
|
};
|
|
886
|
-
|
|
1158
|
+
// The registry operation stays exactly two parameters wide; 'structural'
|
|
1159
|
+
// belongs to the internal call, which knows whether a slot is being filled or
|
|
1160
|
+
// merely read, and every caller outside this file fills one.
|
|
1161
|
+
const reactive = (value, parent = null) => reactiveValue(value, parent, true);
|
|
1162
|
+
const reactiveValue = (value, parent, structural) => {
|
|
887
1163
|
if (value === null || (typeof value !== "object" && typeof value !== "function")) return value;
|
|
888
1164
|
value = toRaw(value);
|
|
889
|
-
if (parent !== null) linkOwner(value, parent);
|
|
1165
|
+
if (parent !== null) linkOwner(value, parent, structural);
|
|
890
1166
|
if (typeof value !== "object" || __velarGraphIsList(value) || !__velarGraphIsExtensible(value)) return value;
|
|
891
1167
|
const prototype = __velarGraphPrototype(value);
|
|
892
1168
|
if (prototype !== __velarGraphNativeObject.prototype && prototype !== null) return value;
|
|
@@ -895,7 +1171,7 @@ function __velarCreateRuntime() {
|
|
|
895
1171
|
proxy = new __velarGraphNativeProxy(value, {
|
|
896
1172
|
get(target, key) {
|
|
897
1173
|
track(target, key);
|
|
898
|
-
return
|
|
1174
|
+
return reactiveValue(__velarGraphGet(target, key, target), target, false);
|
|
899
1175
|
},
|
|
900
1176
|
set(target, key, next) {
|
|
901
1177
|
next = toRaw(next);
|
|
@@ -941,7 +1217,7 @@ function __velarCreateRuntime() {
|
|
|
941
1217
|
// through them. Fresh derived Lists (filter/map/etc.) stay ephemeral and
|
|
942
1218
|
// cannot become strongly retained parents of every item merely by being
|
|
943
1219
|
// iterated during rendering.
|
|
944
|
-
return
|
|
1220
|
+
return reactiveValue(child, __velarGraphWeakMapContains(parents, value) ? value : null, false);
|
|
945
1221
|
};
|
|
946
1222
|
const collectionTrigger = (value, key, iterate = true, structure = false, indexFrom = null, allKeys = false) => trigger(toRaw(value), key, iterate, structure, indexFrom, allKeys);
|
|
947
1223
|
const collectionUnlink = (value, child) => {
|
|
@@ -1115,52 +1391,17 @@ function __velarCreateRuntime() {
|
|
|
1115
1391
|
try { report(error, { phase: "update", detail: "", component: "", unhandled: true }); }
|
|
1116
1392
|
finally { runtime.activeObserver = previousObserver; }
|
|
1117
1393
|
};
|
|
1118
|
-
// The
|
|
1119
|
-
//
|
|
1120
|
-
//
|
|
1121
|
-
//
|
|
1122
|
-
//
|
|
1123
|
-
//
|
|
1124
|
-
//
|
|
1125
|
-
//
|
|
1126
|
-
const scheduleFlush = () => {
|
|
1127
|
-
if (runtime.flushPending) return;
|
|
1128
|
-
runtime.flushPending = true;
|
|
1129
|
-
__velarEnqueue(flush);
|
|
1130
|
-
};
|
|
1131
|
-
const flushOverflow = () => {
|
|
1132
|
-
const stalled = [];
|
|
1133
|
-
for (const observer of __velarGraphSetItems(domQueue)) stalled[stalled.length] = observer;
|
|
1134
|
-
for (const observer of __velarGraphSetItems(watchQueue)) stalled[stalled.length] = observer;
|
|
1135
|
-
__velarGraphSetEmpty(domQueue);
|
|
1136
|
-
__velarGraphSetEmpty(watchQueue);
|
|
1137
|
-
for (let index = 0; index < stalled.length; index += 1) {
|
|
1138
|
-
const observer = stalled[index];
|
|
1139
|
-
if (typeof observer.stop === "function") observer.stop();
|
|
1140
|
-
else observer.stopped = true;
|
|
1141
|
-
}
|
|
1142
|
-
report(new RangeError("Reactive updates cannot run more than 100000 observers in one flush"), { phase: "update", detail: "", component: "", unhandled: true });
|
|
1143
|
-
};
|
|
1144
|
-
const flush = () => {
|
|
1145
|
-
runtime.flushPending = false;
|
|
1146
|
-
let budget = 100000;
|
|
1147
|
-
for (const observer of __velarGraphSetItems(domQueue)) {
|
|
1148
|
-
__velarGraphSetRemove(domQueue, observer);
|
|
1149
|
-
if ((budget -= 1) < 0) { flushOverflow(); return; }
|
|
1150
|
-
observer.run();
|
|
1151
|
-
}
|
|
1152
|
-
for (const observer of __velarGraphSetItems(watchQueue)) {
|
|
1153
|
-
__velarGraphSetRemove(watchQueue, observer);
|
|
1154
|
-
if ((budget -= 1) < 0) { flushOverflow(); return; }
|
|
1155
|
-
observer.run();
|
|
1156
|
-
}
|
|
1157
|
-
if (__velarGraphSetCount(domQueue) || __velarGraphSetCount(watchQueue)) scheduleFlush();
|
|
1158
|
-
};
|
|
1394
|
+
// The queue insert stays on the registry -- computed observers are created by
|
|
1395
|
+
// whichever module stamped it first (velar/app under ESM import order, or the
|
|
1396
|
+
// application prelude) and must schedule correctly whichever that was -- but
|
|
1397
|
+
// the drain it calls is the module-scope one below, and there is now exactly
|
|
1398
|
+
// one of those. A queue that outgrows its bound is the flush budget's failure
|
|
1399
|
+
// to own, not an exception thrown out of the assignment that happened to
|
|
1400
|
+
// cross the line: throwing here left the writing cell's subscriber walk half
|
|
1401
|
+
// finished, with the remaining observers subscribed and never notified again.
|
|
1159
1402
|
const schedule = (observer) => {
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
__velarGraphSetInsert(queue, observer);
|
|
1163
|
-
scheduleFlush();
|
|
1403
|
+
__velarGraphSetInsert(observer.mode === "watch" ? watchQueue : domQueue, observer);
|
|
1404
|
+
__velarScheduleFlush();
|
|
1164
1405
|
};
|
|
1165
1406
|
const applyLook = (...arguments_) => {
|
|
1166
1407
|
if (!lookImplementation) throw new TypeError("Link Look requires the VelarScript Web runtime");
|
|
@@ -1188,7 +1429,18 @@ function __velarCreateRuntime() {
|
|
|
1188
1429
|
}
|
|
1189
1430
|
|
|
1190
1431
|
function __velarRequireRuntime(value) {
|
|
1191
|
-
if (!value || typeof value !== "object"
|
|
1432
|
+
if (!value || typeof value !== "object") throw new TypeError("VelarScript Web runtime ownership is invalid");
|
|
1433
|
+
// The schema comparison comes first, ahead of ownership and the field roster:
|
|
1434
|
+
// a schema bump normally changes the roster too, so leaving it last reported
|
|
1435
|
+
// "fields are invalid" and never named the one fact that identifies the
|
|
1436
|
+
// cause. The version is read through its descriptor rather than the property
|
|
1437
|
+
// so an unvalidated object cannot answer it with a getter.
|
|
1438
|
+
const __velarVersionDescriptor = Object.getOwnPropertyDescriptor(value, "version");
|
|
1439
|
+
const __velarVersion = __velarVersionDescriptor && "value" in __velarVersionDescriptor ? __velarVersionDescriptor.value : undefined;
|
|
1440
|
+
if (__velarVersion !== ${JSON.stringify(VELAR_RUNTIME_SCHEMA_VERSION)}) {
|
|
1441
|
+
throw new TypeError("VelarScript Web runtime schema " + (typeof __velarVersion === "string" ? __velarVersion : "(unknown)") + " does not match this module's schema ${VELAR_RUNTIME_SCHEMA_VERSION}; one build mixed two generations of @velarscript/* — run 'npm ls @velarscript/compiler' and pin one version");
|
|
1442
|
+
}
|
|
1443
|
+
if (Object.getPrototypeOf(value) !== null || Object.isExtensible(value)
|
|
1192
1444
|
|| Object.getOwnPropertySymbols(value).length > 0) throw new TypeError("VelarScript Web runtime ownership is invalid");
|
|
1193
1445
|
const names = Object.getOwnPropertyNames(value);
|
|
1194
1446
|
if (names.length !== __velarRuntimeFields.length || __velarRuntimeFields.some((name) => !names.includes(name))) {
|
|
@@ -1201,8 +1453,7 @@ function __velarRequireRuntime(value) {
|
|
|
1201
1453
|
throw new TypeError("VelarScript Web runtime field '" + name + "' is invalid");
|
|
1202
1454
|
}
|
|
1203
1455
|
}
|
|
1204
|
-
if (value.
|
|
1205
|
-
|| !__velarRuntimeCollection(value.domQueue, "Set") || !__velarRuntimeCollection(value.watchQueue, "Set")
|
|
1456
|
+
if (!__velarRuntimeCollection(value.domQueue, "Set") || !__velarRuntimeCollection(value.watchQueue, "Set")
|
|
1206
1457
|
|| typeof value.flushPending !== "boolean" || (value.activeObserver !== null && typeof value.activeObserver !== "object")
|
|
1207
1458
|
|| !__velarRuntimeCollection(value.errorHandlers, "Set") || !__velarRuntimeCollection(value.actionFailures, "WeakSet")
|
|
1208
1459
|
|| !__velarRuntimeCollection(value.unhandledFailures, "Set")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-foundation.js","sourceRoot":"","sources":["../src/runtime-foundation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAC;AAEzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsa7C,CAAC,SAAS,EAAE,CAAC;AAEd,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"runtime-foundation.js","sourceRoot":"","sources":["../src/runtime-foundation.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAsgBA,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CA8/FvD,CAAC;AAEH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC3D;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,qBAAqC,GAAG,MAAM,GAAG,IAAI,CAUzG"}
|