@joist/templating 4.7.0 → 4.7.1

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 (77) hide show
  1. package/package.json +1 -1
  2. package/target/lib/bind.d.ts +10 -0
  3. package/target/lib/bind.d.ts.map +1 -0
  4. package/target/lib/bind.js +50 -0
  5. package/target/lib/bind.js.map +1 -0
  6. package/target/lib/bind.test.d.ts +2 -0
  7. package/target/lib/bind.test.d.ts.map +1 -0
  8. package/target/lib/bind.test.js +110 -0
  9. package/target/lib/bind.test.js.map +1 -0
  10. package/target/lib/define.d.ts +17 -0
  11. package/target/lib/define.d.ts.map +1 -0
  12. package/target/lib/define.js +14 -0
  13. package/target/lib/define.js.map +1 -0
  14. package/target/lib/elements/async.element.d.ts +14 -0
  15. package/target/lib/elements/async.element.d.ts.map +1 -0
  16. package/target/lib/elements/async.element.js +168 -0
  17. package/target/lib/elements/async.element.js.map +1 -0
  18. package/target/lib/elements/async.element.test.d.ts +2 -0
  19. package/target/lib/elements/async.element.test.d.ts.map +1 -0
  20. package/target/lib/elements/async.element.test.js +191 -0
  21. package/target/lib/elements/async.element.test.js.map +1 -0
  22. package/target/lib/elements/bind.element.d.ts +14 -0
  23. package/target/lib/elements/bind.element.d.ts.map +1 -0
  24. package/target/lib/elements/bind.element.js +180 -0
  25. package/target/lib/elements/bind.element.js.map +1 -0
  26. package/target/lib/elements/bind.element.test.d.ts +2 -0
  27. package/target/lib/elements/bind.element.test.d.ts.map +1 -0
  28. package/target/lib/elements/bind.element.test.js +153 -0
  29. package/target/lib/elements/bind.element.test.js.map +1 -0
  30. package/target/lib/elements/for.element.d.ts +16 -0
  31. package/target/lib/elements/for.element.d.ts.map +1 -0
  32. package/target/lib/elements/for.element.js +259 -0
  33. package/target/lib/elements/for.element.js.map +1 -0
  34. package/target/lib/elements/for.element.test.d.ts +2 -0
  35. package/target/lib/elements/for.element.test.d.ts.map +1 -0
  36. package/target/lib/elements/for.element.test.js +232 -0
  37. package/target/lib/elements/for.element.test.js.map +1 -0
  38. package/target/lib/elements/if.element.d.ts +10 -0
  39. package/target/lib/elements/if.element.d.ts.map +1 -0
  40. package/target/lib/elements/if.element.js +145 -0
  41. package/target/lib/elements/if.element.js.map +1 -0
  42. package/target/lib/elements/if.element.test.d.ts +2 -0
  43. package/target/lib/elements/if.element.test.d.ts.map +1 -0
  44. package/target/lib/elements/if.element.test.js +309 -0
  45. package/target/lib/elements/if.element.test.js.map +1 -0
  46. package/target/lib/elements/scope.element.d.ts +4 -0
  47. package/target/lib/elements/scope.element.d.ts.map +1 -0
  48. package/target/lib/elements/scope.element.js +71 -0
  49. package/target/lib/elements/scope.element.js.map +1 -0
  50. package/target/lib/elements/scope.element.test.d.ts +2 -0
  51. package/target/lib/elements/scope.element.test.d.ts.map +1 -0
  52. package/target/lib/elements/scope.element.test.js +25 -0
  53. package/target/lib/elements/scope.element.test.js.map +1 -0
  54. package/target/lib/elements/value.element.d.ts +6 -0
  55. package/target/lib/elements/value.element.d.ts.map +1 -0
  56. package/target/lib/elements/value.element.js +96 -0
  57. package/target/lib/elements/value.element.js.map +1 -0
  58. package/target/lib/elements/value.element.test.d.ts +2 -0
  59. package/target/lib/elements/value.element.test.d.ts.map +1 -0
  60. package/target/lib/elements/value.element.test.js +68 -0
  61. package/target/lib/elements/value.element.test.js.map +1 -0
  62. package/target/lib/events.d.ts +17 -0
  63. package/target/lib/events.d.ts.map +1 -0
  64. package/target/lib/events.js +10 -0
  65. package/target/lib/events.js.map +1 -0
  66. package/target/lib/expression.d.ts +65 -0
  67. package/target/lib/expression.d.ts.map +1 -0
  68. package/target/lib/expression.js +153 -0
  69. package/target/lib/expression.js.map +1 -0
  70. package/target/lib/expression.test.d.ts +2 -0
  71. package/target/lib/expression.test.d.ts.map +1 -0
  72. package/target/lib/expression.test.js +171 -0
  73. package/target/lib/expression.test.js.map +1 -0
  74. package/target/lib.d.ts +3 -0
  75. package/target/lib.d.ts.map +1 -0
  76. package/target/lib.js +3 -0
  77. package/target/lib.js.map +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joist/templating",
3
- "version": "4.7.0",
3
+ "version": "4.7.1",
4
4
  "type": "module",
5
5
  "main": "./target/lib.js",
6
6
  "module": "./target/lib.js",
@@ -0,0 +1,10 @@
1
+ import type { ObserveOpts } from "@joist/observable";
2
+ export interface BindOpts<This, Value> extends ObserveOpts<This, Value> {
3
+ /**
4
+ * Trigger bindings on every change cycle, regardless of value,
5
+ * newValue and oldValue will be the same in that case
6
+ **/
7
+ alwaysUpdate?: boolean;
8
+ }
9
+ export declare function bind<This extends HTMLElement, Value>(opts?: BindOpts<This, Value>): (base: ClassAccessorDecoratorTarget<This, Value>, ctx: ClassAccessorDecoratorContext<This, Value>) => ClassAccessorDecoratorResult<This, Value>;
10
+ //# sourceMappingURL=bind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../src/lib/bind.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAE,SAAQ,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC;IACrE;;;QAGI;IACJ,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,IAAI,CAAC,IAAI,SAAS,WAAW,EAAE,KAAK,EAAE,IAAI,GAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAM,IAElF,MAAM,4BAA4B,CAAC,IAAI,EAAE,KAAK,CAAC,EAC/C,KAAK,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,KAC9C,4BAA4B,CAAC,IAAI,EAAE,KAAK,CAAC,CAyD7C"}
@@ -0,0 +1,50 @@
1
+ import { instanceMetadataStore, observe } from "@joist/observable";
2
+ export function bind(opts = {}) {
3
+ return function bindDecorator(base, ctx) {
4
+ const internalObserve = observe(opts)(base, ctx);
5
+ const accessorResult = {
6
+ init(value) {
7
+ this.addEventListener("joist::value", (e) => {
8
+ if (e.expression.bindTo === ctx.name) {
9
+ const instanceMeta = instanceMetadataStore.read(this);
10
+ e.stopPropagation();
11
+ e.update({
12
+ oldValue: null,
13
+ newValue: ctx.access.get(this),
14
+ alwaysUpdate: opts.alwaysUpdate,
15
+ firstChange: true,
16
+ });
17
+ const name = ctx.name;
18
+ instanceMeta.bindings.add((changes) => {
19
+ const change = changes.get(name);
20
+ if (change) {
21
+ e.update({ ...change, alwaysUpdate: opts.alwaysUpdate, firstChange: false });
22
+ }
23
+ else if (opts.alwaysUpdate) {
24
+ const value = ctx.access.get(this);
25
+ e.update({
26
+ oldValue: value,
27
+ newValue: value,
28
+ alwaysUpdate: opts.alwaysUpdate,
29
+ firstChange: false,
30
+ });
31
+ }
32
+ });
33
+ }
34
+ });
35
+ if (internalObserve.init) {
36
+ return internalObserve.init.call(this, value);
37
+ }
38
+ return value;
39
+ },
40
+ };
41
+ if (internalObserve.get) {
42
+ accessorResult.get = internalObserve.get;
43
+ }
44
+ if (internalObserve.set) {
45
+ accessorResult.set = internalObserve.set;
46
+ }
47
+ return accessorResult;
48
+ };
49
+ }
50
+ //# sourceMappingURL=bind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.js","sourceRoot":"","sources":["../../src/lib/bind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAWnE,MAAM,UAAU,IAAI,CAAkC,OAA8B,EAAE;IACpF,OAAO,SAAS,aAAa,CAC3B,IAA+C,EAC/C,GAA+C;QAE/C,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEjD,MAAM,cAAc,GAA8C;YAChE,IAAI,CAAC,KAAK;gBACR,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE;oBAC1C,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;wBACrC,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,CAAO,IAAI,CAAC,CAAC;wBAE5D,CAAC,CAAC,eAAe,EAAE,CAAC;wBAEpB,CAAC,CAAC,MAAM,CAAC;4BACP,QAAQ,EAAE,IAAI;4BACd,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;4BAC9B,YAAY,EAAE,IAAI,CAAC,YAAY;4BAC/B,WAAW,EAAE,IAAI;yBAClB,CAAC,CAAC;wBAEH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAkB,CAAC;wBAEpC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;4BACpC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BAEjC,IAAI,MAAM,EAAE,CAAC;gCACX,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;4BAC/E,CAAC;iCAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gCAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gCAEnC,CAAC,CAAC,MAAM,CAAC;oCACP,QAAQ,EAAE,KAAK;oCACf,QAAQ,EAAE,KAAK;oCACf,YAAY,EAAE,IAAI,CAAC,YAAY;oCAC/B,WAAW,EAAE,KAAK;iCACnB,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,IAAI,eAAe,CAAC,IAAI,EAAE,CAAC;oBACzB,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAU,CAAC;gBACzD,CAAC;gBAED,OAAO,KAAK,CAAC;YACf,CAAC;SACF,CAAC;QAEF,IAAI,eAAe,CAAC,GAAG,EAAE,CAAC;YACxB,cAAc,CAAC,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC;QAC3C,CAAC;QAED,IAAI,eAAe,CAAC,GAAG,EAAE,CAAC;YACxB,cAAc,CAAC,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC;QAC3C,CAAC;QAED,OAAO,cAAc,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bind.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.test.d.ts","sourceRoot":"","sources":["../../src/lib/bind.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,110 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { assert } from "chai";
36
+ import { bind } from "./bind.js";
37
+ import { JoistValueEvent } from "./events.js";
38
+ import { JExpression } from "./expression.js";
39
+ describe("bind decorator", () => {
40
+ let TestElement = (() => {
41
+ let _classSuper = HTMLElement;
42
+ let _value_decorators;
43
+ let _value_initializers = [];
44
+ let _value_extraInitializers = [];
45
+ let _alwaysUpdateValue_decorators;
46
+ let _alwaysUpdateValue_initializers = [];
47
+ let _alwaysUpdateValue_extraInitializers = [];
48
+ return class TestElement extends _classSuper {
49
+ static {
50
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
51
+ _value_decorators = [bind()];
52
+ _alwaysUpdateValue_decorators = [bind({ alwaysUpdate: true })];
53
+ __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
54
+ __esDecorate(this, null, _alwaysUpdateValue_decorators, { kind: "accessor", name: "alwaysUpdateValue", static: false, private: false, access: { has: obj => "alwaysUpdateValue" in obj, get: obj => obj.alwaysUpdateValue, set: (obj, value) => { obj.alwaysUpdateValue = value; } }, metadata: _metadata }, _alwaysUpdateValue_initializers, _alwaysUpdateValue_extraInitializers);
55
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
56
+ }
57
+ #value_accessor_storage = __runInitializers(this, _value_initializers, "initial");
58
+ get value() { return this.#value_accessor_storage; }
59
+ set value(value) { this.#value_accessor_storage = value; }
60
+ #alwaysUpdateValue_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _alwaysUpdateValue_initializers, "initial"));
61
+ get alwaysUpdateValue() { return this.#alwaysUpdateValue_accessor_storage; }
62
+ set alwaysUpdateValue(value) { this.#alwaysUpdateValue_accessor_storage = value; }
63
+ constructor() {
64
+ super(...arguments);
65
+ __runInitializers(this, _alwaysUpdateValue_extraInitializers);
66
+ }
67
+ };
68
+ })();
69
+ customElements.define("test-element", TestElement);
70
+ it("should initialize with default value", () => {
71
+ const element = new TestElement();
72
+ assert.equal(element.value, "initial");
73
+ });
74
+ it("should update value and trigger binding", async () => {
75
+ const element = new TestElement();
76
+ let oldValue = null;
77
+ let newValue = null;
78
+ element.dispatchEvent(new JoistValueEvent(new JExpression("value"), (update) => {
79
+ oldValue = update.oldValue;
80
+ newValue = update.newValue;
81
+ }));
82
+ assert.equal(oldValue, null);
83
+ assert.equal(newValue, "initial");
84
+ element.value = "updated";
85
+ await Promise.resolve();
86
+ assert.equal(oldValue, "initial");
87
+ assert.equal(newValue, "updated");
88
+ });
89
+ it("should trigger binding on every change with alwaysUpdate option", async () => {
90
+ const element = new TestElement();
91
+ let bindingCount = 0;
92
+ let oldValue;
93
+ let newValue;
94
+ element.dispatchEvent(new JoistValueEvent(new JExpression("alwaysUpdateValue"), (update) => {
95
+ bindingCount++;
96
+ oldValue = update.oldValue;
97
+ newValue = update.newValue;
98
+ }));
99
+ assert.equal(bindingCount, 1);
100
+ assert.equal(oldValue, null);
101
+ assert.equal(newValue, "initial");
102
+ // Change some other value in the model
103
+ element.value = "something else";
104
+ await Promise.resolve();
105
+ assert.equal(bindingCount, 2);
106
+ assert.equal(oldValue, "initial");
107
+ assert.equal(newValue, "initial");
108
+ });
109
+ });
110
+ //# sourceMappingURL=bind.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.test.js","sourceRoot":"","sources":["../../src/lib/bind.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { JoistAsyncElement } from "./elements/async.element.js";
2
+ import { JoistForElement } from "./elements/for.element.js";
3
+ import { JoistIfElement } from "./elements/if.element.js";
4
+ import { JoistBindElement } from "./elements/bind.element.js";
5
+ import { JoistValueElement } from "./elements/value.element.js";
6
+ import { JoistScopeElement } from "./elements/scope.element.js";
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ "j-async": JoistAsyncElement;
10
+ "j-for": JoistForElement;
11
+ "j-if": JoistIfElement;
12
+ "j-bind": JoistBindElement;
13
+ "j-val": JoistValueElement;
14
+ "j-scope": JoistScopeElement;
15
+ }
16
+ }
17
+ //# sourceMappingURL=define.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/lib/define.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,iBAAiB,CAAC;QAC7B,OAAO,EAAE,eAAe,CAAC;QACzB,MAAM,EAAE,cAAc,CAAC;QACvB,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,OAAO,EAAE,iBAAiB,CAAC;QAC3B,SAAS,EAAE,iBAAiB,CAAC;KAC9B;CACF"}
@@ -0,0 +1,14 @@
1
+ import { define } from "@joist/element/define.js";
2
+ import { JoistAsyncElement } from "./elements/async.element.js";
3
+ import { JoistForElement } from "./elements/for.element.js";
4
+ import { JoistIfElement } from "./elements/if.element.js";
5
+ import { JoistBindElement } from "./elements/bind.element.js";
6
+ import { JoistValueElement } from "./elements/value.element.js";
7
+ import { JoistScopeElement } from "./elements/scope.element.js";
8
+ define({ tagName: "j-async" }, JoistAsyncElement);
9
+ define({ tagName: "j-for" }, JoistForElement);
10
+ define({ tagName: "j-if" }, JoistIfElement);
11
+ define({ tagName: "j-bind" }, JoistBindElement);
12
+ define({ tagName: "j-val" }, JoistValueElement);
13
+ define({ tagName: "j-scope" }, JoistScopeElement);
14
+ //# sourceMappingURL=define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/lib/define.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAahE,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,iBAAiB,CAAC,CAAC;AAClD,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAC9C,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC;AAC5C,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAChD,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;AAChD,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type AsyncState<T = unknown, E = unknown> = {
2
+ status: "loading" | "error" | "success";
3
+ data?: T;
4
+ error?: E;
5
+ };
6
+ export declare class JoistAsyncElement extends HTMLElement {
7
+ #private;
8
+ accessor bind: string;
9
+ accessor dependsOn: string;
10
+ accessor state: AsyncState | null;
11
+ connectedCallback(): Promise<void>;
12
+ disconnectedCallback(): void;
13
+ }
14
+ //# sourceMappingURL=async.element.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.element.d.ts","sourceRoot":"","sources":["../../../src/lib/elements/async.element.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI;IACjD,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,CAAC,CAAC;CACX,CAAC;AAEF,qBAIa,iBAAkB,SAAQ,WAAW;;IAEhD,QAAQ,CAAC,IAAI,SAAM;IAKnB,QAAQ,CAAC,SAAS,SAAM;IAGxB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAQ;IAcnC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0FxC,oBAAoB,IAAI,IAAI;CAG7B"}
@@ -0,0 +1,168 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { attr, element, queryAll, css, html } from "@joist/element";
36
+ import { bind } from "../bind.js";
37
+ import { JoistValueEvent } from "../events.js";
38
+ import { JExpression } from "../expression.js";
39
+ let JoistAsyncElement = (() => {
40
+ let _classDecorators = [element({
41
+ // prettier-ignore
42
+ shadowDom: [css `:host{display: contents;}`, html `<slot></slot>`],
43
+ })];
44
+ let _classDescriptor;
45
+ let _classExtraInitializers = [];
46
+ let _classThis;
47
+ let _classSuper = HTMLElement;
48
+ let _bind_decorators;
49
+ let _bind_initializers = [];
50
+ let _bind_extraInitializers = [];
51
+ let _dependsOn_decorators;
52
+ let _dependsOn_initializers = [];
53
+ let _dependsOn_extraInitializers = [];
54
+ let _state_decorators;
55
+ let _state_initializers = [];
56
+ let _state_extraInitializers = [];
57
+ var JoistAsyncElement = class extends _classSuper {
58
+ static { _classThis = this; }
59
+ static {
60
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
61
+ _bind_decorators = [attr()];
62
+ _dependsOn_decorators = [attr({
63
+ name: "depends-on",
64
+ })];
65
+ _state_decorators = [bind()];
66
+ __esDecorate(this, null, _bind_decorators, { kind: "accessor", name: "bind", static: false, private: false, access: { has: obj => "bind" in obj, get: obj => obj.bind, set: (obj, value) => { obj.bind = value; } }, metadata: _metadata }, _bind_initializers, _bind_extraInitializers);
67
+ __esDecorate(this, null, _dependsOn_decorators, { kind: "accessor", name: "dependsOn", static: false, private: false, access: { has: obj => "dependsOn" in obj, get: obj => obj.dependsOn, set: (obj, value) => { obj.dependsOn = value; } }, metadata: _metadata }, _dependsOn_initializers, _dependsOn_extraInitializers);
68
+ __esDecorate(this, null, _state_decorators, { kind: "accessor", name: "state", static: false, private: false, access: { has: obj => "state" in obj, get: obj => obj.state, set: (obj, value) => { obj.state = value; } }, metadata: _metadata }, _state_initializers, _state_extraInitializers);
69
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
70
+ JoistAsyncElement = _classThis = _classDescriptor.value;
71
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
72
+ __runInitializers(_classThis, _classExtraInitializers);
73
+ }
74
+ #bind_accessor_storage = __runInitializers(this, _bind_initializers, "");
75
+ get bind() { return this.#bind_accessor_storage; }
76
+ set bind(value) { this.#bind_accessor_storage = value; }
77
+ #dependsOn_accessor_storage = (__runInitializers(this, _bind_extraInitializers), __runInitializers(this, _dependsOn_initializers, ""));
78
+ get dependsOn() { return this.#dependsOn_accessor_storage; }
79
+ set dependsOn(value) { this.#dependsOn_accessor_storage = value; }
80
+ #state_accessor_storage = (__runInitializers(this, _dependsOn_extraInitializers), __runInitializers(this, _state_initializers, null));
81
+ get state() { return this.#state_accessor_storage; }
82
+ set state(value) { this.#state_accessor_storage = value; }
83
+ #templates = (__runInitializers(this, _state_extraInitializers), queryAll("template", this));
84
+ #currentNodes = [];
85
+ #cachedTemplates = {
86
+ loading: undefined,
87
+ error: undefined,
88
+ success: undefined,
89
+ };
90
+ async connectedCallback() {
91
+ this.#clean();
92
+ // Cache all templates
93
+ const templates = Array.from(this.#templates());
94
+ this.#cachedTemplates = {
95
+ loading: templates.find((t) => t.hasAttribute("loading")),
96
+ error: templates.find((t) => t.hasAttribute("error")),
97
+ success: templates.find((t) => t.hasAttribute("success")),
98
+ };
99
+ if (this.dependsOn) {
100
+ await Promise.all(this.dependsOn.split(",").map((tag) => window.customElements.whenDefined(tag)));
101
+ }
102
+ const token = new JExpression(this.bind);
103
+ this.dispatchEvent(new JoistValueEvent(token, ({ newValue, oldValue }) => {
104
+ if (newValue !== oldValue) {
105
+ if (newValue instanceof Promise) {
106
+ this.#handlePromise(newValue);
107
+ }
108
+ else if (this.#isAsyncState(newValue)) {
109
+ this.#handleState(newValue);
110
+ }
111
+ else {
112
+ console.warn("j-async bind value must be a Promise or AsyncState");
113
+ }
114
+ }
115
+ }));
116
+ }
117
+ #isAsyncState(value) {
118
+ return (typeof value === "object" &&
119
+ value !== null &&
120
+ "status" in value &&
121
+ (value.status === "loading" || value.status === "error" || value.status === "success"));
122
+ }
123
+ async #handlePromise(promise) {
124
+ try {
125
+ this.#handleState({ status: "loading" });
126
+ const data = await promise;
127
+ this.#handleState({ status: "success", data });
128
+ }
129
+ catch (error) {
130
+ this.#handleState({ status: "error", error });
131
+ }
132
+ }
133
+ #handleState(state) {
134
+ this.#clean();
135
+ let template;
136
+ this.state = state;
137
+ switch (state.status) {
138
+ case "loading":
139
+ template = this.#cachedTemplates.loading;
140
+ break;
141
+ case "error":
142
+ template = this.#cachedTemplates.error;
143
+ break;
144
+ case "success":
145
+ template = this.#cachedTemplates.success;
146
+ break;
147
+ }
148
+ if (template) {
149
+ const content = document.importNode(template.content, true);
150
+ const nodes = Array.from(content.childNodes);
151
+ this.appendChild(content);
152
+ this.#currentNodes = nodes;
153
+ }
154
+ }
155
+ #clean() {
156
+ for (const node of this.#currentNodes) {
157
+ node.parentNode?.removeChild(node);
158
+ }
159
+ this.#currentNodes = [];
160
+ }
161
+ disconnectedCallback() {
162
+ this.#clean();
163
+ }
164
+ };
165
+ return JoistAsyncElement = _classThis;
166
+ })();
167
+ export { JoistAsyncElement };
168
+ //# sourceMappingURL=async.element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.element.js","sourceRoot":"","sources":["../../../src/lib/elements/async.element.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;IAYlC,iBAAiB;4BAJ7B,OAAO,CAAC;YACP,kBAAkB;YAClB,SAAS,EAAE,CAAC,GAAG,CAAA,2BAA2B,EAAE,IAAI,CAAA,eAAe,CAAC;SACjE,CAAC;;;;sBACqC,WAAW;;;;;;;;;;iCAAnB,SAAQ,WAAW;;;;gCAC/C,IAAI,EAAE;qCAGN,IAAI,CAAC;oBACJ,IAAI,EAAE,YAAY;iBACnB,CAAC;iCAGD,IAAI,EAAE;YAPP,iKAAS,IAAI,6BAAJ,IAAI,mFAAM;YAKnB,gLAAS,SAAS,6BAAT,SAAS,6FAAM;YAGxB,oKAAS,KAAK,6BAAL,KAAK,qFAA2B;YAV3C,6KAqHC;;;YArHY,uDAAiB;;QAE5B,qEAAgB,EAAE,EAAC;QAAnB,IAAS,IAAI,0CAAM;QAAnB,IAAS,IAAI,gDAAM;QAKnB,kIAAqB,EAAE,GAAC;QAAxB,IAAS,SAAS,+CAAM;QAAxB,IAAS,SAAS,qDAAM;QAGxB,+HAAoC,IAAI,GAAC;QAAzC,IAAS,KAAK,2CAA2B;QAAzC,IAAS,KAAK,iDAA2B;QAEzC,UAAU,uDAAG,QAAQ,CAAsB,UAAU,EAAE,IAAI,CAAC,EAAC;QAC7D,aAAa,GAAW,EAAE,CAAC;QAC3B,gBAAgB,GAIZ;YACF,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,SAAS;SACnB,CAAC;QAEF,KAAK,CAAC,iBAAiB;YACrB,IAAI,CAAC,MAAM,EAAE,CAAC;YAEd,sBAAsB;YACtB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAEhD,IAAI,CAAC,gBAAgB,GAAG;gBACtB,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;gBACzD,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;gBACrD,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;aAC1D,CAAC;YAEF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAC/E,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEzC,IAAI,CAAC,aAAa,CAChB,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACpD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC1B,IAAI,QAAQ,YAAY,OAAO,EAAE,CAAC;wBAChC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;oBAChC,CAAC;yBAAM,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACxC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;oBAC9B,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;oBACrE,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;QAED,aAAa,CAAC,KAAc;YAC1B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;gBACzB,KAAK,KAAK,IAAI;gBACd,QAAQ,IAAI,KAAK;gBACjB,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CACvF,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,OAAyB;YAC5C,IAAI,CAAC;gBACH,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACzC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;gBAC3B,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAED,YAAY,CAAC,KAAiB;YAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YAEd,IAAI,QAAyC,CAAC;YAE9C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YAEnB,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;gBACrB,KAAK,SAAS;oBACZ,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;oBACzC,MAAM;gBAER,KAAK,OAAO;oBACV,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;oBACvC,MAAM;gBAER,KAAK,SAAS;oBACZ,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;oBACzC,MAAM;YACV,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC7C,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBAC1B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,MAAM;YACJ,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACtC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QAC1B,CAAC;QAED,oBAAoB;YAClB,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;;;;SApHU,iBAAiB"}
@@ -0,0 +1,2 @@
1
+ import "../define.js";
2
+ //# sourceMappingURL=async.element.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.element.test.d.ts","sourceRoot":"","sources":["../../../src/lib/elements/async.element.test.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC"}
@@ -0,0 +1,191 @@
1
+ import "../define.js";
2
+ import { fixtureSync, html } from "@open-wc/testing";
3
+ import { assert } from "chai";
4
+ it("should show loading template when promise is pending", async () => {
5
+ const element = fixtureSync(html `
6
+ <div
7
+ @joist::value=${(e) => {
8
+ e.update({ oldValue: null, newValue: new Promise(() => { }) });
9
+ }}
10
+ >
11
+ <j-async bind="test">
12
+ <template loading>Loading...</template>
13
+ <template success>Success!</template>
14
+ <template error>Error!</template>
15
+ </j-async>
16
+ </div>
17
+ `);
18
+ assert.equal(element.textContent?.trim(), "Loading...");
19
+ });
20
+ it("should show success template when promise resolves", async () => {
21
+ const element = fixtureSync(html `
22
+ <div
23
+ @joist::value=${(e) => {
24
+ e.update({ oldValue: null, newValue: Promise.resolve("data") });
25
+ }}
26
+ >
27
+ <j-async bind="test">
28
+ <template loading>Loading...</template>
29
+ <template success>Success!</template>
30
+ <template error>Error!</template>
31
+ </j-async>
32
+ </div>
33
+ `);
34
+ // Wait for promise to resolve
35
+ await new Promise((resolve) => setTimeout(resolve, 0));
36
+ assert.equal(element.textContent?.trim(), "Success!");
37
+ });
38
+ it("should show error template when promise rejects", async () => {
39
+ const element = fixtureSync(html `
40
+ <div
41
+ @joist::value=${(e) => {
42
+ e.update({ oldValue: null, newValue: Promise.reject("error") });
43
+ }}
44
+ >
45
+ <j-async bind="test">
46
+ <template loading>Loading...</template>
47
+ <template success>Success!</template>
48
+ <template error>Error!</template>
49
+ </j-async>
50
+ </div>
51
+ `);
52
+ // Wait for promise to reject
53
+ await new Promise((resolve) => setTimeout(resolve, 0));
54
+ assert.equal(element.textContent?.trim(), "Error!");
55
+ });
56
+ it("should handle state transitions", async () => {
57
+ const element = fixtureSync(html `
58
+ <div
59
+ @joist::value=${(e) => {
60
+ const promise = new Promise((resolve) => {
61
+ setTimeout(() => resolve("data"), 100);
62
+ });
63
+ e.update({ oldValue: null, newValue: promise });
64
+ }}
65
+ >
66
+ <j-async bind="test">
67
+ <template loading>Loading...</template>
68
+ <template success>Success!</template>
69
+ <template error>Error!</template>
70
+ </j-async>
71
+ </div>
72
+ `);
73
+ // Initially should show loading
74
+ assert.equal(element.textContent?.trim(), "Loading...");
75
+ // Wait for promise to resolve
76
+ await new Promise((resolve) => setTimeout(resolve, 150));
77
+ assert.equal(element.textContent?.trim(), "Success!");
78
+ });
79
+ it("should show loading template when AsyncState is loading", () => {
80
+ const element = fixtureSync(html `
81
+ <div
82
+ @joist::value=${(e) => {
83
+ e.update({ oldValue: null, newValue: { status: "loading" } });
84
+ }}
85
+ >
86
+ <j-async bind="test">
87
+ <template loading>Loading...</template>
88
+ <template success>Success!</template>
89
+ <template error>Error!</template>
90
+ </j-async>
91
+ </div>
92
+ `);
93
+ assert.equal(element.textContent?.trim(), "Loading...");
94
+ });
95
+ it("should show success template when AsyncState is success", () => {
96
+ const element = fixtureSync(html `
97
+ <div
98
+ @joist::value=${(e) => {
99
+ e.update({ oldValue: null, newValue: { status: "success", data: "test data" } });
100
+ }}
101
+ >
102
+ <j-async bind="test">
103
+ <template loading>Loading...</template>
104
+ <template success>Success!</template>
105
+ <template error>Error!</template>
106
+ </j-async>
107
+ </div>
108
+ `);
109
+ assert.equal(element.textContent?.trim(), "Success!");
110
+ });
111
+ it("should show error template when AsyncState is error", () => {
112
+ const element = fixtureSync(html `
113
+ <div
114
+ @joist::value=${(e) => {
115
+ e.update({ oldValue: null, newValue: { status: "error", error: "test error" } });
116
+ }}
117
+ >
118
+ <j-async bind="test">
119
+ <template loading>Loading...</template>
120
+ <template success>Success!</template>
121
+ <template error>Error!</template>
122
+ </j-async>
123
+ </div>
124
+ `);
125
+ assert.equal(element.textContent?.trim(), "Error!");
126
+ });
127
+ it("should handle AsyncState transitions", () => {
128
+ const element = fixtureSync(html `
129
+ <div
130
+ @joist::value=${(e) => {
131
+ // Initial state
132
+ e.update({ oldValue: null, newValue: { status: "loading" } });
133
+ // Simulate state transition after a short delay
134
+ setTimeout(() => {
135
+ e.update({
136
+ oldValue: { status: "loading" },
137
+ newValue: { status: "success", data: "test data" },
138
+ });
139
+ }, 100);
140
+ }}
141
+ >
142
+ <j-async bind="test">
143
+ <template loading>Loading...</template>
144
+ <template success>Success!</template>
145
+ <template error>Error!</template>
146
+ </j-async>
147
+ </div>
148
+ `);
149
+ // Initially should show loading
150
+ assert.equal(element.textContent?.trim(), "Loading...");
151
+ // Wait for state transition
152
+ return new Promise((resolve) => {
153
+ setTimeout(() => {
154
+ assert.equal(element.textContent?.trim(), "Success!");
155
+ resolve(undefined);
156
+ }, 150);
157
+ });
158
+ });
159
+ it("should wait for depends-on before dispatching events", async () => {
160
+ let eventDispatched = false;
161
+ customElements.define("dependency-1", class extends HTMLElement {
162
+ });
163
+ customElements.define("dependency-2", class extends HTMLElement {
164
+ });
165
+ fixtureSync(html `
166
+ <div
167
+ @joist::value=${(e) => {
168
+ if (e.expression.bindTo === "test") {
169
+ eventDispatched = true;
170
+ e.update({ oldValue: null, newValue: Promise.resolve("data") });
171
+ }
172
+ }}
173
+ >
174
+ <j-async bind="test" depends-on="dependency-1,dependency-2">
175
+ <template loading>Loading...</template>
176
+ <template success>Success!</template>
177
+ <template error>Error!</template>
178
+ </j-async>
179
+ </div>
180
+ `);
181
+ // Initially, no event should be dispatched
182
+ assert.isFalse(eventDispatched);
183
+ // Wait for the custom elements to be defined
184
+ await Promise.all([
185
+ customElements.whenDefined("dependency-1"),
186
+ customElements.whenDefined("dependency-2"),
187
+ ]);
188
+ // Now the event should be dispatched
189
+ assert.isTrue(eventDispatched);
190
+ });
191
+ //# sourceMappingURL=async.element.test.js.map