@livetemplate/client 0.1.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.
Files changed (100) hide show
  1. package/README.md +179 -0
  2. package/dist/constants.d.ts +2 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +19 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/dom/directives.d.ts +13 -0
  7. package/dist/dom/directives.d.ts.map +1 -0
  8. package/dist/dom/directives.js +137 -0
  9. package/dist/dom/directives.js.map +1 -0
  10. package/dist/dom/event-delegation.d.ts +24 -0
  11. package/dist/dom/event-delegation.d.ts.map +1 -0
  12. package/dist/dom/event-delegation.js +437 -0
  13. package/dist/dom/event-delegation.js.map +1 -0
  14. package/dist/dom/focus-manager.d.ts +19 -0
  15. package/dist/dom/focus-manager.d.ts.map +1 -0
  16. package/dist/dom/focus-manager.js +144 -0
  17. package/dist/dom/focus-manager.js.map +1 -0
  18. package/dist/dom/form-disabler.d.ts +8 -0
  19. package/dist/dom/form-disabler.d.ts.map +1 -0
  20. package/dist/dom/form-disabler.js +32 -0
  21. package/dist/dom/form-disabler.js.map +1 -0
  22. package/dist/dom/loading-indicator.d.ts +9 -0
  23. package/dist/dom/loading-indicator.d.ts.map +1 -0
  24. package/dist/dom/loading-indicator.js +50 -0
  25. package/dist/dom/loading-indicator.js.map +1 -0
  26. package/dist/dom/modal-manager.d.ts +11 -0
  27. package/dist/dom/modal-manager.d.ts.map +1 -0
  28. package/dist/dom/modal-manager.js +62 -0
  29. package/dist/dom/modal-manager.js.map +1 -0
  30. package/dist/dom/observer-manager.d.ts +19 -0
  31. package/dist/dom/observer-manager.d.ts.map +1 -0
  32. package/dist/dom/observer-manager.js +64 -0
  33. package/dist/dom/observer-manager.js.map +1 -0
  34. package/dist/livetemplate-client.browser.js +44 -0
  35. package/dist/livetemplate-client.browser.js.map +7 -0
  36. package/dist/livetemplate-client.d.ts +106 -0
  37. package/dist/livetemplate-client.d.ts.map +1 -0
  38. package/dist/livetemplate-client.js +507 -0
  39. package/dist/livetemplate-client.js.map +1 -0
  40. package/dist/state/form-lifecycle-manager.d.ts +19 -0
  41. package/dist/state/form-lifecycle-manager.d.ts.map +1 -0
  42. package/dist/state/form-lifecycle-manager.js +64 -0
  43. package/dist/state/form-lifecycle-manager.js.map +1 -0
  44. package/dist/state/tree-renderer.d.ts +27 -0
  45. package/dist/state/tree-renderer.d.ts.map +1 -0
  46. package/dist/state/tree-renderer.js +359 -0
  47. package/dist/state/tree-renderer.js.map +1 -0
  48. package/dist/tests/event-delegation.test.d.ts +2 -0
  49. package/dist/tests/event-delegation.test.d.ts.map +1 -0
  50. package/dist/tests/event-delegation.test.js +102 -0
  51. package/dist/tests/event-delegation.test.js.map +1 -0
  52. package/dist/tests/focus-manager.test.d.ts +2 -0
  53. package/dist/tests/focus-manager.test.d.ts.map +1 -0
  54. package/dist/tests/focus-manager.test.js +45 -0
  55. package/dist/tests/focus-manager.test.js.map +1 -0
  56. package/dist/tests/form-disabler.test.d.ts +2 -0
  57. package/dist/tests/form-disabler.test.d.ts.map +1 -0
  58. package/dist/tests/form-disabler.test.js +35 -0
  59. package/dist/tests/form-disabler.test.js.map +1 -0
  60. package/dist/tests/form-lifecycle-manager.test.d.ts +2 -0
  61. package/dist/tests/form-lifecycle-manager.test.d.ts.map +1 -0
  62. package/dist/tests/form-lifecycle-manager.test.js +90 -0
  63. package/dist/tests/form-lifecycle-manager.test.js.map +1 -0
  64. package/dist/tests/modal-manager.test.d.ts +2 -0
  65. package/dist/tests/modal-manager.test.d.ts.map +1 -0
  66. package/dist/tests/modal-manager.test.js +80 -0
  67. package/dist/tests/modal-manager.test.js.map +1 -0
  68. package/dist/tests/rate-limit.test.d.ts +2 -0
  69. package/dist/tests/rate-limit.test.d.ts.map +1 -0
  70. package/dist/tests/rate-limit.test.js +38 -0
  71. package/dist/tests/rate-limit.test.js.map +1 -0
  72. package/dist/tests/test-conditional-debug.test.d.ts +8 -0
  73. package/dist/tests/test-conditional-debug.test.d.ts.map +1 -0
  74. package/dist/tests/test-conditional-debug.test.js +187 -0
  75. package/dist/tests/test-conditional-debug.test.js.map +1 -0
  76. package/dist/tests/test-reconstruction.test.d.ts +8 -0
  77. package/dist/tests/test-reconstruction.test.d.ts.map +1 -0
  78. package/dist/tests/test-reconstruction.test.js +284 -0
  79. package/dist/tests/test-reconstruction.test.js.map +1 -0
  80. package/dist/transport/websocket.d.ts +62 -0
  81. package/dist/transport/websocket.d.ts.map +1 -0
  82. package/dist/transport/websocket.js +194 -0
  83. package/dist/transport/websocket.js.map +1 -0
  84. package/dist/types.d.ts +34 -0
  85. package/dist/types.d.ts.map +1 -0
  86. package/dist/types.js +3 -0
  87. package/dist/types.js.map +1 -0
  88. package/dist/utils/logger.d.ts +32 -0
  89. package/dist/utils/logger.d.ts.map +1 -0
  90. package/dist/utils/logger.js +77 -0
  91. package/dist/utils/logger.js.map +1 -0
  92. package/dist/utils/rate-limit.d.ts +10 -0
  93. package/dist/utils/rate-limit.d.ts.map +1 -0
  94. package/dist/utils/rate-limit.js +37 -0
  95. package/dist/utils/rate-limit.js.map +1 -0
  96. package/dist/utils/testing.d.ts +14 -0
  97. package/dist/utils/testing.d.ts.map +1 -0
  98. package/dist/utils/testing.js +51 -0
  99. package/dist/utils/testing.js.map +1 -0
  100. package/package.json +57 -0
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const form_lifecycle_manager_1 = require("../state/form-lifecycle-manager");
4
+ const modal_manager_1 = require("../dom/modal-manager");
5
+ const logger_1 = require("../utils/logger");
6
+ describe("FormLifecycleManager", () => {
7
+ let modalCloseSpy;
8
+ let modalManager;
9
+ beforeEach(() => {
10
+ modalManager = new modal_manager_1.ModalManager((0, logger_1.createLogger)({ scope: "ModalManagerTest", level: "silent" }));
11
+ modalCloseSpy = jest
12
+ .spyOn(modalManager, "close")
13
+ .mockImplementation(() => { });
14
+ document.body.innerHTML = "";
15
+ });
16
+ afterEach(() => {
17
+ modalCloseSpy.mockRestore();
18
+ document.body.innerHTML = "";
19
+ });
20
+ const createForm = () => {
21
+ const modal = document.createElement("div");
22
+ modal.id = "modal-1";
23
+ modal.setAttribute("role", "dialog");
24
+ const form = document.createElement("form");
25
+ modal.appendChild(form);
26
+ const button = document.createElement("button");
27
+ button.textContent = "Submit";
28
+ form.appendChild(button);
29
+ document.body.appendChild(modal);
30
+ return { form, button, modal };
31
+ };
32
+ it("dispatches success events, resets the form, and closes the modal on success", () => {
33
+ const { form, button, modal } = createForm();
34
+ const manager = new form_lifecycle_manager_1.FormLifecycleManager(modalManager);
35
+ const doneListener = jest.fn();
36
+ const successListener = jest.fn();
37
+ form.addEventListener("lvt:done", doneListener);
38
+ form.addEventListener("lvt:success", successListener);
39
+ manager.setActiveSubmission(form, button, "Submit");
40
+ const metadata = { success: true, errors: {} };
41
+ manager.handleResponse(metadata);
42
+ expect(doneListener).toHaveBeenCalledWith(expect.any(CustomEvent));
43
+ expect(successListener).toHaveBeenCalledWith(expect.any(CustomEvent));
44
+ expect(modalCloseSpy).toHaveBeenCalledWith("modal-1");
45
+ expect(form.elements.length).toBeGreaterThan(0);
46
+ expect(button.disabled).toBe(false);
47
+ expect(button.textContent).toBe("Submit");
48
+ });
49
+ it("respects lvt-preserve and keeps the fields intact", () => {
50
+ const { form, button } = createForm();
51
+ form.setAttribute("lvt-preserve", "");
52
+ const input = document.createElement("input");
53
+ input.value = "Keep me";
54
+ form.appendChild(input);
55
+ const manager = new form_lifecycle_manager_1.FormLifecycleManager(modalManager);
56
+ manager.setActiveSubmission(form, button, "Submit");
57
+ const metadata = { success: true, errors: {} };
58
+ manager.handleResponse(metadata);
59
+ expect(input.value).toBe("Keep me");
60
+ });
61
+ it("dispatches error events and keeps the form when the response fails", () => {
62
+ const { form, button } = createForm();
63
+ const manager = new form_lifecycle_manager_1.FormLifecycleManager(modalManager);
64
+ const doneListener = jest.fn();
65
+ const errorListener = jest.fn();
66
+ form.addEventListener("lvt:done", doneListener);
67
+ form.addEventListener("lvt:error", errorListener);
68
+ manager.setActiveSubmission(form, button, "Submit");
69
+ const metadata = {
70
+ success: false,
71
+ errors: { title: "Required" },
72
+ };
73
+ manager.handleResponse(metadata);
74
+ expect(doneListener).toHaveBeenCalledWith(expect.any(CustomEvent));
75
+ expect(errorListener).toHaveBeenCalledWith(expect.any(CustomEvent));
76
+ expect(modalCloseSpy).not.toHaveBeenCalled();
77
+ expect(button.disabled).toBe(false);
78
+ expect(button.textContent).toBe("Submit");
79
+ });
80
+ it("reset simply clears active submission state", () => {
81
+ const { form, button } = createForm();
82
+ const manager = new form_lifecycle_manager_1.FormLifecycleManager(modalManager);
83
+ manager.setActiveSubmission(form, button, "Submit");
84
+ manager.reset();
85
+ const metadata = { success: true, errors: {} };
86
+ manager.handleResponse(metadata);
87
+ expect(modalCloseSpy).not.toHaveBeenCalled();
88
+ });
89
+ });
90
+ //# sourceMappingURL=form-lifecycle-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-lifecycle-manager.test.js","sourceRoot":"","sources":["../../tests/form-lifecycle-manager.test.ts"],"names":[],"mappings":";;AAAA,4EAAuE;AACvE,wDAAoD;AACpD,4CAA+C;AAG/C,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,IAAI,aAA+B,CAAC;IACpC,IAAI,YAA0B,CAAC;IAE/B,UAAU,CAAC,GAAG,EAAE;QACd,YAAY,GAAG,IAAI,4BAAY,CAC7B,IAAA,qBAAY,EAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAC7D,CAAC;QACF,aAAa,GAAG,IAAI;aACjB,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC;aAC5B,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,CAAC,WAAW,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5C,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC;QACrB,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAErC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5C,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAExB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC9B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAEzB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEjC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACjC,CAAC,CAAC;IAEF,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,6CAAoB,CAAC,YAAY,CAAC,CAAC;QAEvD,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,eAAe,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAChD,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QAEtD,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACjE,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACtE,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAEtC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAExB,MAAM,OAAO,GAAG,IAAI,6CAAoB,CAAC,YAAY,CAAC,CAAC;QACvD,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACjE,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,6CAAoB,CAAC,YAAY,CAAC,CAAC;QAEvD,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAChC,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAChD,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAElD,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAqB;YACjC,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE;SAC9B,CAAC;QACF,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,6CAAoB,CAAC,YAAY,CAAC,CAAC;QAEvD,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,MAAM,QAAQ,GAAqB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACjE,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=modal-manager.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-manager.test.d.ts","sourceRoot":"","sources":["../../tests/modal-manager.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const modal_manager_1 = require("../dom/modal-manager");
4
+ const logger_1 = require("../utils/logger");
5
+ describe("ModalManager", () => {
6
+ let consoleLogSpy;
7
+ let consoleWarnSpy;
8
+ beforeEach(() => {
9
+ consoleLogSpy = jest.spyOn(console, "log").mockImplementation(() => { });
10
+ consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation(() => { });
11
+ document.body.innerHTML = "";
12
+ });
13
+ afterEach(() => {
14
+ consoleLogSpy.mockRestore();
15
+ consoleWarnSpy.mockRestore();
16
+ jest.useRealTimers();
17
+ document.body.innerHTML = "";
18
+ });
19
+ it("opens a modal and focuses the first input when no element is active", () => {
20
+ jest.useFakeTimers();
21
+ const modal = document.createElement("div");
22
+ modal.id = "test-modal";
23
+ modal.setAttribute("hidden", "");
24
+ modal.style.display = "none";
25
+ modal.setAttribute("aria-hidden", "true");
26
+ const input = document.createElement("input");
27
+ input.type = "text";
28
+ modal.appendChild(input);
29
+ document.body.appendChild(modal);
30
+ const manager = new modal_manager_1.ModalManager((0, logger_1.createLogger)({ scope: "ModalManagerTest", level: "silent" }));
31
+ const openedListener = jest.fn();
32
+ modal.addEventListener("lvt:modal-opened", openedListener);
33
+ manager.open("test-modal");
34
+ expect(modal.hasAttribute("hidden")).toBe(false);
35
+ expect(modal.style.display).toBe("flex");
36
+ expect(modal.getAttribute("aria-hidden")).toBe("false");
37
+ expect(openedListener).toHaveBeenCalled();
38
+ jest.runAllTimers();
39
+ expect(document.activeElement).toBe(input);
40
+ });
41
+ it("respects the current focus when a visible element inside the modal is already active", () => {
42
+ jest.useFakeTimers();
43
+ const modal = document.createElement("div");
44
+ modal.id = "test-modal-visible";
45
+ modal.setAttribute("hidden", "");
46
+ modal.style.display = "none";
47
+ modal.setAttribute("aria-hidden", "true");
48
+ const firstInput = document.createElement("input");
49
+ firstInput.type = "text";
50
+ const secondInput = document.createElement("input");
51
+ secondInput.type = "text";
52
+ // Emulate layout visibility checks performed in ModalManager.
53
+ Object.defineProperty(secondInput, "offsetParent", {
54
+ get: () => modal,
55
+ });
56
+ secondInput.getClientRects = () => [{ width: 10, height: 10 }];
57
+ modal.appendChild(firstInput);
58
+ modal.appendChild(secondInput);
59
+ document.body.appendChild(modal);
60
+ const manager = new modal_manager_1.ModalManager((0, logger_1.createLogger)({ scope: "ModalManagerTest", level: "silent" }));
61
+ manager.open("test-modal-visible");
62
+ secondInput.focus();
63
+ jest.runAllTimers();
64
+ expect(document.activeElement).toBe(secondInput);
65
+ });
66
+ it("closes a modal and emits the closed event", () => {
67
+ const modal = document.createElement("div");
68
+ modal.id = "test-modal-close";
69
+ document.body.appendChild(modal);
70
+ const manager = new modal_manager_1.ModalManager((0, logger_1.createLogger)({ scope: "ModalManagerTest", level: "silent" }));
71
+ const closedListener = jest.fn();
72
+ modal.addEventListener("lvt:modal-closed", closedListener);
73
+ manager.close("test-modal-close");
74
+ expect(modal.hasAttribute("hidden")).toBe(true);
75
+ expect(modal.style.display).toBe("none");
76
+ expect(modal.getAttribute("aria-hidden")).toBe("true");
77
+ expect(closedListener).toHaveBeenCalled();
78
+ });
79
+ });
80
+ //# sourceMappingURL=modal-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-manager.test.js","sourceRoot":"","sources":["../../tests/modal-manager.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rate-limit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.test.d.ts","sourceRoot":"","sources":["../../tests/rate-limit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const rate_limit_1 = require("../utils/rate-limit");
4
+ describe("rate limit utilities", () => {
5
+ beforeEach(() => {
6
+ jest.useFakeTimers();
7
+ });
8
+ afterEach(() => {
9
+ jest.useRealTimers();
10
+ });
11
+ it("debounce delays invocation until the wait period has elapsed", () => {
12
+ const spy = jest.fn();
13
+ const debounced = (0, rate_limit_1.debounce)(spy, 300);
14
+ debounced();
15
+ debounced();
16
+ debounced();
17
+ expect(spy).not.toHaveBeenCalled();
18
+ jest.advanceTimersByTime(299);
19
+ expect(spy).not.toHaveBeenCalled();
20
+ jest.advanceTimersByTime(1);
21
+ expect(spy).toHaveBeenCalledTimes(1);
22
+ });
23
+ it("throttle executes immediately and then rate limits subsequent calls", () => {
24
+ const spy = jest.fn();
25
+ const throttled = (0, rate_limit_1.throttle)(spy, 200);
26
+ throttled();
27
+ throttled();
28
+ throttled();
29
+ expect(spy).toHaveBeenCalledTimes(1);
30
+ jest.advanceTimersByTime(199);
31
+ throttled();
32
+ expect(spy).toHaveBeenCalledTimes(1);
33
+ jest.advanceTimersByTime(1);
34
+ throttled();
35
+ expect(spy).toHaveBeenCalledTimes(2);
36
+ });
37
+ });
38
+ //# sourceMappingURL=rate-limit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.test.js","sourceRoot":"","sources":["../../tests/rate-limit.test.ts"],"names":[],"mappings":";;AAAA,oDAAyD;AAEzD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,UAAU,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,IAAA,qBAAQ,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAErC,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QAEZ,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAEnC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAEnC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACtB,MAAM,SAAS,GAAG,IAAA,qBAAQ,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAErC,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;QAEZ,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAErC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC9B,SAAS,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAErC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC5B,SAAS,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Test Conditional Rendering - Debug [object Object] Issue
3
+ *
4
+ * This test debugs the conditional rendering bug where conditional nodes
5
+ * render as [object Object] instead of HTML.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=test-conditional-debug.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-conditional-debug.test.d.ts","sourceRoot":"","sources":["../../tests/test-conditional-debug.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ /**
3
+ * Test Conditional Rendering - Debug [object Object] Issue
4
+ *
5
+ * This test debugs the conditional rendering bug where conditional nodes
6
+ * render as [object Object] instead of HTML.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const livetemplate_client_1 = require("../livetemplate-client");
10
+ describe('Conditional Rendering Debug Tests', () => {
11
+ let client;
12
+ beforeEach(() => {
13
+ client = new livetemplate_client_1.LiveTemplateClient();
14
+ });
15
+ test('Simple conditional: false -> true transition', () => {
16
+ console.log('\n=== TEST: Simple Conditional False -> True ===\n');
17
+ // Step 1: Initial state with conditional = false
18
+ const initialTree = {
19
+ "0": "",
20
+ "s": [
21
+ "\n<div>\n<h1>Title</h1>\n",
22
+ "\n</div>\n"
23
+ ]
24
+ };
25
+ console.log('Step 1: Apply initial tree (conditional = false)');
26
+ console.log('Initial tree:', JSON.stringify(initialTree, null, 2));
27
+ const result1 = client.applyUpdate(initialTree);
28
+ console.log('Result HTML:', result1.html);
29
+ console.log('Result changed:', result1.changed);
30
+ console.log('Client treeState:', JSON.stringify(client.getTreeState(), null, 2));
31
+ expect(result1.html).toContain('<h1>Title</h1>');
32
+ expect(result1.html).not.toContain('Message is shown');
33
+ expect(result1.html).not.toContain('[object Object]');
34
+ // Step 2: Update to show conditional (false -> true)
35
+ const update = {
36
+ "0": {
37
+ "s": ["\n<p>Message is shown</p>\n"]
38
+ }
39
+ };
40
+ console.log('\nStep 2: Apply update (conditional = true)');
41
+ console.log('Update:', JSON.stringify(update, null, 2));
42
+ const result2 = client.applyUpdate(update);
43
+ console.log('Result HTML:', result2.html);
44
+ console.log('Result changed:', result2.changed);
45
+ console.log('Client treeState after update:', JSON.stringify(client.getTreeState(), null, 2));
46
+ // THIS IS THE BUG: The HTML should contain the message, not [object Object]
47
+ console.log('\n=== CHECKING FOR BUG ===');
48
+ if (result2.html.includes('[object Object]')) {
49
+ console.error('❌ BUG DETECTED: HTML contains [object Object]');
50
+ console.error('Full HTML:', result2.html);
51
+ }
52
+ else if (result2.html.includes('Message is shown')) {
53
+ console.log('✅ SUCCESS: Conditional rendered correctly');
54
+ }
55
+ else {
56
+ console.error('❌ UNEXPECTED: Message not found and no [object Object]');
57
+ console.error('Full HTML:', result2.html);
58
+ }
59
+ expect(result2.html).toContain('Message is shown');
60
+ expect(result2.html).not.toContain('[object Object]');
61
+ });
62
+ test('Conditional with search results (mimics Search_Functionality)', () => {
63
+ console.log('\n=== TEST: Search Results Conditional ===\n');
64
+ // Initial state: list with items (send as range structure, not operations)
65
+ const initialTree = {
66
+ "0": {
67
+ "d": [
68
+ { "0": "todo-1", "1": "First Todo" },
69
+ { "0": "todo-2", "1": "Second Todo" }
70
+ ],
71
+ "s": ["<tr data-key=\"", "\"><td>", "</td></tr>"]
72
+ },
73
+ "1": "",
74
+ "s": ["<table><tbody>", "</tbody></table>\n", "\n"]
75
+ };
76
+ console.log('Step 1: Apply initial tree (has items)');
77
+ const result1 = client.applyUpdate(initialTree);
78
+ console.log('Result HTML:', result1.html);
79
+ expect(result1.html).toContain('First Todo');
80
+ expect(result1.html).toContain('Second Todo');
81
+ // Update: empty results with "no results" conditional (ACTUAL SERVER OUTPUT)
82
+ const update = {
83
+ "0": [
84
+ ["r", "todo-1"],
85
+ ["r", "todo-2"]
86
+ ],
87
+ "1": {
88
+ "0": {
89
+ "0": "NonExistent",
90
+ "s": ["\n<small>No todos found matching \"", "\"</small>\n"]
91
+ },
92
+ "1": "",
93
+ "s": ["\n<p>\n", "\n", "\n</p>\n"]
94
+ }
95
+ };
96
+ console.log('\nStep 2: Apply update (empty results + conditional message)');
97
+ console.log('Update:', JSON.stringify(update, null, 2));
98
+ const result2 = client.applyUpdate(update);
99
+ console.log('Result HTML:', result2.html);
100
+ console.log('Client treeState:', JSON.stringify(client.getTreeState(), null, 2));
101
+ // THIS IS THE BUG IN Search_Functionality
102
+ console.log('\n=== CHECKING FOR BUG ===');
103
+ if (result2.html.includes('[object Object]')) {
104
+ console.error('❌ BUG DETECTED: HTML contains [object Object]');
105
+ console.error('Full HTML:', result2.html);
106
+ console.error('This is the Search_Functionality bug!');
107
+ }
108
+ else if (result2.html.includes('No todos found')) {
109
+ console.log('✅ SUCCESS: Conditional rendered correctly');
110
+ }
111
+ else {
112
+ console.error('❌ UNEXPECTED: Message not found and no [object Object]');
113
+ console.error('Full HTML:', result2.html);
114
+ }
115
+ expect(result2.html).not.toContain('[object Object]');
116
+ expect(result2.html).toContain('No todos found');
117
+ });
118
+ test('Deep dive: Inspect renderValue with conditional node', () => {
119
+ console.log('\n=== TEST: Deep Dive - renderValue Behavior ===\n');
120
+ // Create a conditional node
121
+ const conditionalNode = {
122
+ "s": ["\n<p>Message is shown</p>\n"]
123
+ };
124
+ console.log('Testing renderValue with conditional node:');
125
+ console.log('Input:', JSON.stringify(conditionalNode, null, 2));
126
+ // Call renderValue directly (via applyUpdate which calls reconstructFromTree which calls renderValue)
127
+ const testTree = {
128
+ "0": conditionalNode,
129
+ "s": ["<div>", "</div>"]
130
+ };
131
+ const result = client.applyUpdate(testTree);
132
+ console.log('Output HTML:', result.html);
133
+ // Check if the conditional node was processed correctly
134
+ const hasObjectString = result.html.includes('[object Object]');
135
+ const hasMessage = result.html.includes('Message is shown');
136
+ console.log('Has [object Object]:', hasObjectString);
137
+ console.log('Has message:', hasMessage);
138
+ if (hasObjectString) {
139
+ console.error('\n❌ PROBLEM IDENTIFIED:');
140
+ console.error('The conditional node {"s": [...]} is being converted to [object Object]');
141
+ console.error('This means renderValue is not detecting it as a tree node');
142
+ console.error('Check the condition at livetemplate-client.ts:1431');
143
+ }
144
+ expect(result.html).not.toContain('[object Object]');
145
+ expect(result.html).toContain('Message is shown');
146
+ });
147
+ test('Verify tree node detection logic', () => {
148
+ console.log('\n=== TEST: Tree Node Detection Logic ===\n');
149
+ const testCases = [
150
+ {
151
+ name: 'Conditional node (only s)',
152
+ value: { "s": ["<p>Test</p>"] },
153
+ shouldBeTree: true,
154
+ expectedHTML: '<p>Test</p>'
155
+ },
156
+ {
157
+ name: 'Tree node with dynamics',
158
+ value: { "0": "dynamic", "s": ["<p>", "</p>"] },
159
+ shouldBeTree: true,
160
+ expectedHTML: '<p>dynamic</p>'
161
+ },
162
+ {
163
+ name: 'Range node',
164
+ value: { "d": [{ "0": "item1" }], "s": ["<li>", "</li>"] },
165
+ shouldBeTree: false, // Should be detected as range
166
+ expectedHTML: '<li>item1</li>'
167
+ },
168
+ {
169
+ name: 'Empty object',
170
+ value: {},
171
+ shouldBeTree: false,
172
+ expectedHTML: '[object Object]' // Will fail, but documents behavior
173
+ }
174
+ ];
175
+ testCases.forEach(testCase => {
176
+ console.log(`\nTest case: ${testCase.name}`);
177
+ console.log('Value:', JSON.stringify(testCase.value, null, 2));
178
+ const tree = { "0": testCase.value, "s": ["<div>", "</div>"] };
179
+ const result = client.applyUpdate(tree);
180
+ console.log('Result HTML:', result.html);
181
+ console.log('Contains expected:', result.html.includes(testCase.expectedHTML.replace(/<[^>]*>/g, m => m)));
182
+ // Reset client for next test
183
+ client = new livetemplate_client_1.LiveTemplateClient();
184
+ });
185
+ });
186
+ });
187
+ //# sourceMappingURL=test-conditional-debug.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-conditional-debug.test.js","sourceRoot":"","sources":["../../tests/test-conditional-debug.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Test HTML Reconstruction from LiveTemplate Updates
3
+ *
4
+ * This test verifies that the TypeScript client can correctly reconstruct
5
+ * HTML from tree-based updates by comparing with actual rendered HTML.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=test-reconstruction.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-reconstruction.test.d.ts","sourceRoot":"","sources":["../../tests/test-reconstruction.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}