mithril-lynx 2.6.0 → 2.6.2
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/.omo/run-continuation/ses_f2f02336cffeO0ssvuxqZ05iZq.json +10 -0
- package/.omo/run-continuation/ses_f2fd5cb5fffeN1tjdUyPqdKG6B.json +10 -0
- package/LICENSE.txt +21 -0
- package/PLAN_REVIEW.md +134 -0
- package/README.md +2 -1
- package/REQUEST.md +5 -2
- package/ROUTE.md +1 -1
- package/informe-contrato-mithril-lynx.md +206 -0
- package/package.json +1 -1
- package/prompts-analisis-contrato-mithril-lynx.md +141 -0
- package/src/apply-patch.js +41 -10
- package/src/backends/virtual-backend.js +1 -1
- package/src/background.d.ts +14 -1
- package/src/channel.js +10 -2
- package/src/list-support.js +29 -3
- package/src/main-thread.js +15 -2
- package/src/mount-redraw.d.ts +10 -0
- package/src/mount-redraw.js +55 -2
- package/src/patch-protocol.js +16 -2
- package/src/request.d.ts +2 -0
- package/src/request.js +21 -3
- package/src/route.d.ts +22 -3
- package/src/route.js +25 -6
- package/src/testing.js +24 -11
- package/test/list.test.ts +19 -1
- package/test/patch-protocol.test.ts +41 -0
- package/test/remove-event.test.ts +26 -0
- package/test/route-hot-reload.test.ts +2 -1
- package/test/route.test.ts +5 -2
- package/test/setup.ts +10 -0
- package/.omo/run-continuation/ses_f48265d07ffenKG0GAz9ZRFvY6.json +0 -10
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it } from "@rstest/core";
|
|
2
|
+
import { createPatchApplier } from "../src/apply-patch.js";
|
|
3
|
+
import { Op } from "../src/patch-protocol.js";
|
|
4
|
+
|
|
5
|
+
// R3: Op.RemoveEvent must actually remove the native listener, not silently
|
|
6
|
+
// no-op — otherwise a remove→re-add cycle on a kept element accumulates
|
|
7
|
+
// duplicate native listeners and the app's handler fires N times per event
|
|
8
|
+
// (see informe-contrato-mithril-lynx.md §R3).
|
|
9
|
+
describe("Op.RemoveEvent removes the native listener (no duplicate-fire leak)", () => {
|
|
10
|
+
it("AddEvent → RemoveEvent → AddEvent leaves exactly one listener", () => {
|
|
11
|
+
lynxTestingEnv.switchToMainThread();
|
|
12
|
+
const pageId = __GetElementUniqueID(__CreatePage());
|
|
13
|
+
const applier = createPatchApplier(pageId);
|
|
14
|
+
applier.registerPageRoot(__CreateView(pageId));
|
|
15
|
+
|
|
16
|
+
applier.applyPatch([Op.CreateElement, "view", 1, Op.AddEvent, 1, "tap"]);
|
|
17
|
+
const handle = applier.getHandle(1) as any;
|
|
18
|
+
expect(handle.__vanillaListeners.tap.size).toBe(1);
|
|
19
|
+
|
|
20
|
+
applier.applyPatch([Op.RemoveEvent, 1, "tap"]);
|
|
21
|
+
expect(handle.__vanillaListeners.tap.size).toBe(0);
|
|
22
|
+
|
|
23
|
+
applier.applyPatch([Op.AddEvent, 1, "tap"]);
|
|
24
|
+
expect(handle.__vanillaListeners.tap.size).toBe(1);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -15,7 +15,8 @@ describe("route.js + stable-host: a same-path re-resolve patches in place, never
|
|
|
15
15
|
lynxTestingEnv.switchToMainThread();
|
|
16
16
|
const capturedOps: unknown[][] = [];
|
|
17
17
|
lynx.getJSContext().addEventListener("MithrilLynx:Patch", (event: any) => {
|
|
18
|
-
|
|
18
|
+
// event.data is [PROTOCOL_VERSION, ...ops] — drop the version prefix.
|
|
19
|
+
capturedOps.push(event.data.slice(1));
|
|
19
20
|
});
|
|
20
21
|
|
|
21
22
|
lynxTestingEnv.switchToBackgroundThread();
|
package/test/route.test.ts
CHANGED
|
@@ -22,9 +22,12 @@ function setupRealTree() {
|
|
|
22
22
|
// tree inspected.
|
|
23
23
|
lynxTestingEnv.switchToMainThread();
|
|
24
24
|
lynx.getJSContext().addEventListener("MithrilLynx:Patch", (event: any) => {
|
|
25
|
-
|
|
25
|
+
// event.data is [PROTOCOL_VERSION, ...ops] — mirror main-thread.js's
|
|
26
|
+
// own onPatch by stripping the version prefix before applying.
|
|
27
|
+
const ops = event.data.slice(1);
|
|
28
|
+
capturedOps.push(ops);
|
|
26
29
|
lynxTestingEnv.switchToMainThread();
|
|
27
|
-
applier.applyPatch(
|
|
30
|
+
applier.applyPatch(ops);
|
|
28
31
|
});
|
|
29
32
|
|
|
30
33
|
return { applier, capturedOps };
|
package/test/setup.ts
CHANGED
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
// for everyone else (src/testing.js's installTestingPolyfills) — see that
|
|
5
5
|
// file's header for what it covers and why.
|
|
6
6
|
|
|
7
|
+
import { afterEach } from "@rstest/core";
|
|
7
8
|
import { installTestingPolyfills } from "../src/testing.js";
|
|
9
|
+
import { unregister } from "../src/mount-redraw.js";
|
|
8
10
|
|
|
9
11
|
globalThis.onInjectMainThreadGlobals = installTestingPolyfills;
|
|
12
|
+
|
|
13
|
+
// mount-redraw.js is a single-slot singleton and register() now fails fast
|
|
14
|
+
// on a second registration (R2) — clear it between tests so each test's own
|
|
15
|
+
// renderApp() starts from a clean slate instead of colliding with the
|
|
16
|
+
// previous test's still-registered redraw.
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
unregister();
|
|
19
|
+
});
|