@tachui/data 0.8.1-alpha → 0.8.8
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/List.js +2794 -202
- package/dist/Menu.js +157 -159
- package/dist/index.js +0 -1
- package/dist/list/List.d.ts +8 -1
- package/dist/list/List.d.ts.map +1 -1
- package/dist/list/index.js +0 -1
- package/dist/menu/Menu.d.ts +5 -0
- package/dist/menu/Menu.d.ts.map +1 -1
- package/dist/menu/index.js +0 -1
- package/package.json +8 -5
- package/dist/List.js.map +0 -1
- package/dist/Menu.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/list/index.js.map +0 -1
- package/dist/menu/index.js.map +0 -1
package/dist/List.js
CHANGED
|
@@ -1,118 +1,2717 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { createSignal as
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
var de = Object.defineProperty;
|
|
2
|
+
var ue = (n, e, t) => e in n ? de(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var u = (n, e, t) => ue(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { withModifiers as re, createSignal as A, isSignal as v, createEffect as I, h as b } from "@tachui/core";
|
|
5
|
+
import "@tachui/modifiers";
|
|
6
|
+
const g = {
|
|
7
|
+
Clean: 0,
|
|
8
|
+
Check: 1,
|
|
9
|
+
Dirty: 2,
|
|
10
|
+
Disposed: 3
|
|
11
|
+
};
|
|
12
|
+
var pe = Object.defineProperty, fe = (n, e, t) => e in n ? pe(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, M = (n, e, t) => fe(n, typeof e != "symbol" ? e + "" : e, t);
|
|
13
|
+
let me = 0;
|
|
14
|
+
const ge = Math.random().toString(36).substr(2, 6);
|
|
15
|
+
let Z = null, J = null;
|
|
16
|
+
const ye = /* @__PURE__ */ new Set();
|
|
17
|
+
ye.add(ge);
|
|
18
|
+
const D = {
|
|
19
|
+
get currentComputation() {
|
|
20
|
+
return Z;
|
|
21
|
+
},
|
|
22
|
+
set currentComputation(n) {
|
|
23
|
+
Z = n;
|
|
24
|
+
},
|
|
25
|
+
get currentOwner() {
|
|
26
|
+
return J;
|
|
27
|
+
},
|
|
28
|
+
set currentOwner(n) {
|
|
29
|
+
J = n;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
function ie() {
|
|
33
|
+
return D.currentComputation;
|
|
34
|
+
}
|
|
35
|
+
function ne() {
|
|
36
|
+
return D.currentOwner;
|
|
37
|
+
}
|
|
38
|
+
let oe = class {
|
|
39
|
+
constructor(e, t = null) {
|
|
40
|
+
M(this, "id"), M(this, "owner"), M(this, "fn"), M(this, "sources", /* @__PURE__ */ new Set()), M(this, "observers", /* @__PURE__ */ new Set()), M(this, "state", g.Dirty), M(this, "value"), this.id = ++me, this.fn = e, this.owner = t, t && !t.disposed && t.sources.add(this);
|
|
41
|
+
}
|
|
42
|
+
execute() {
|
|
43
|
+
if (this.state === g.Disposed)
|
|
44
|
+
return this.value;
|
|
45
|
+
for (const t of this.sources)
|
|
46
|
+
t && typeof t == "object" && "removeObserver" in t && t.removeObserver(this);
|
|
47
|
+
this.sources.clear();
|
|
48
|
+
const e = D.currentComputation;
|
|
49
|
+
D.currentComputation = this;
|
|
50
|
+
try {
|
|
51
|
+
return this.state = g.Clean, this.value = this.fn(), this.value;
|
|
52
|
+
} catch (t) {
|
|
53
|
+
throw this.state = g.Disposed, (typeof process > "u" || process.env.NODE_ENV !== "test") && console.error("Error in computation:", t), t;
|
|
54
|
+
} finally {
|
|
55
|
+
D.currentComputation = e;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
dispose() {
|
|
59
|
+
if (this.state !== g.Disposed) {
|
|
60
|
+
this.state = g.Disposed;
|
|
61
|
+
for (const e of this.sources)
|
|
62
|
+
e && typeof e == "object" && "removeObserver" in e && e.removeObserver(this);
|
|
63
|
+
this.sources.clear();
|
|
64
|
+
for (const e of this.observers)
|
|
65
|
+
e.sources.delete(this);
|
|
66
|
+
this.observers.clear(), this.owner && !this.owner.disposed && this.owner.sources.delete(this);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var ve = Object.defineProperty, be = (n, e, t) => e in n ? ve(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, B = (n, e, t) => be(n, typeof e != "symbol" ? e + "" : e, t);
|
|
71
|
+
let Se = 0, Ce = class {
|
|
72
|
+
constructor(e) {
|
|
73
|
+
B(this, "id"), B(this, "observers", /* @__PURE__ */ new Set()), B(this, "_value"), this.id = ++Se, this._value = e;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the current value and track dependency
|
|
77
|
+
*/
|
|
78
|
+
getValue() {
|
|
79
|
+
const e = ie();
|
|
80
|
+
return e && e.state !== g.Disposed && (this.observers.add(e), e.sources.add(this)), this._value;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the current value without tracking dependency
|
|
84
|
+
*/
|
|
85
|
+
peek() {
|
|
86
|
+
return this._value;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Set a new value and notify observers
|
|
90
|
+
*/
|
|
91
|
+
set(e) {
|
|
92
|
+
const t = typeof e == "function" ? e(this._value) : e;
|
|
93
|
+
return t !== this._value && (this._value = t, this.notify()), t;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Notify all observers that this signal has changed
|
|
97
|
+
*/
|
|
98
|
+
notify() {
|
|
99
|
+
for (const e of this.observers)
|
|
100
|
+
e.state !== g.Disposed && (e.state = g.Dirty, Ee(e));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Remove an observer (cleanup)
|
|
104
|
+
*/
|
|
105
|
+
removeObserver(e) {
|
|
106
|
+
this.observers.delete(e);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get debug information about this signal
|
|
110
|
+
*/
|
|
111
|
+
[Symbol.for("tachui.debug")]() {
|
|
112
|
+
return {
|
|
113
|
+
id: this.id,
|
|
114
|
+
value: this._value,
|
|
115
|
+
observerCount: this.observers.size,
|
|
116
|
+
type: "Signal"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const U = /* @__PURE__ */ new Set();
|
|
121
|
+
let j = !1;
|
|
122
|
+
function Ee(n) {
|
|
123
|
+
U.add(n), !j && queueMicrotask(we);
|
|
124
|
+
}
|
|
125
|
+
function we() {
|
|
126
|
+
if (!j) {
|
|
127
|
+
j = !0;
|
|
128
|
+
try {
|
|
129
|
+
for (; U.size > 0; ) {
|
|
130
|
+
const n = Array.from(U).sort((e, t) => e.id - t.id);
|
|
131
|
+
U.clear();
|
|
132
|
+
for (const e of n)
|
|
133
|
+
e.state === g.Dirty && e.execute();
|
|
134
|
+
}
|
|
135
|
+
} finally {
|
|
136
|
+
j = !1;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function G(n) {
|
|
141
|
+
const e = new Ce(n), t = e.getValue.bind(e);
|
|
142
|
+
t.peek = e.peek.bind(e);
|
|
143
|
+
const s = e.set.bind(e);
|
|
144
|
+
return Object.defineProperty(t, Symbol.for("tachui.signal"), {
|
|
145
|
+
value: e,
|
|
146
|
+
enumerable: !1
|
|
147
|
+
}), [t, s];
|
|
148
|
+
}
|
|
149
|
+
function T(n) {
|
|
150
|
+
return typeof n == "function" && Symbol.for("tachui.signal") in n;
|
|
151
|
+
}
|
|
152
|
+
const Ae = (n, e) => n === e;
|
|
153
|
+
var Ie = Object.defineProperty, Me = (n, e, t) => e in n ? Ie(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, S = (n, e, t) => Me(n, typeof e != "symbol" ? e + "" : e, t), _ = /* @__PURE__ */ ((n) => (n[n.Immediate = 0] = "Immediate", n[n.High = 1] = "High", n[n.Normal = 2] = "Normal", n[n.Low = 3] = "Low", n[n.Idle = 4] = "Idle", n))(_ || {});
|
|
154
|
+
let Ne = class extends Error {
|
|
155
|
+
constructor(e, t, s) {
|
|
156
|
+
super(e), this.cause = t, this.node = s, this.name = "ReactiveError";
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const xe = class $ {
|
|
160
|
+
constructor() {
|
|
161
|
+
S(this, "updateQueues", /* @__PURE__ */ new Map()), S(this, "isFlushPending", !1), S(this, "isDestroyed", !1), S(this, "errorHandlers", /* @__PURE__ */ new Set()), S(this, "maxRetries", 3), S(this, "totalUpdateCycles", 0), S(this, "totalUpdateTime", 0), S(this, "errorCount", 0), S(this, "nodeRegistry", /* @__PURE__ */ new WeakSet());
|
|
162
|
+
for (const e of Object.values(_))
|
|
163
|
+
typeof e == "number" && this.updateQueues.set(e, /* @__PURE__ */ new Set());
|
|
164
|
+
}
|
|
165
|
+
static getInstance() {
|
|
166
|
+
return $.instance || ($.instance = new $()), $.instance;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Schedule reactive node for update
|
|
170
|
+
*/
|
|
171
|
+
schedule(e) {
|
|
172
|
+
this.isDestroyed || (this.nodeRegistry.add(e), this.getQueue(e.priority).add(e), this.isFlushPending || (this.isFlushPending = !0, this.scheduleFlush(e.priority)));
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Process all queued updates by priority
|
|
176
|
+
*/
|
|
177
|
+
async flush() {
|
|
178
|
+
if (this.isDestroyed) return;
|
|
179
|
+
this.isFlushPending = !1;
|
|
180
|
+
const e = performance.now();
|
|
181
|
+
try {
|
|
182
|
+
for (const t of [
|
|
183
|
+
0,
|
|
184
|
+
1,
|
|
185
|
+
2,
|
|
186
|
+
3,
|
|
187
|
+
4
|
|
188
|
+
/* Idle */
|
|
189
|
+
]) {
|
|
190
|
+
const s = this.updateQueues.get(t);
|
|
191
|
+
if (!s || s.size === 0) continue;
|
|
192
|
+
const r = Array.from(s);
|
|
193
|
+
s.clear();
|
|
194
|
+
for (const i of r)
|
|
195
|
+
try {
|
|
196
|
+
await this.updateNodeWithRetry(i);
|
|
197
|
+
} catch (o) {
|
|
198
|
+
this.handleReactiveError(
|
|
199
|
+
new Ne(`Failed to update ${i.type} node ${i.id}`, o, i)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
if (this.hasHigherPriorityWork(t))
|
|
203
|
+
return this.flush();
|
|
204
|
+
}
|
|
205
|
+
this.totalUpdateCycles++;
|
|
206
|
+
} finally {
|
|
207
|
+
const t = performance.now();
|
|
208
|
+
this.totalUpdateTime += t - e;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Update node with retry logic
|
|
213
|
+
*/
|
|
214
|
+
async updateNodeWithRetry(e, t = 1) {
|
|
215
|
+
try {
|
|
216
|
+
e.notify();
|
|
217
|
+
} catch (s) {
|
|
218
|
+
if (t < this.maxRetries)
|
|
219
|
+
return console.warn(`Reactive update failed, retrying (${t}/${this.maxRetries})`), await new Promise((r) => setTimeout(r, t * 10)), this.updateNodeWithRetry(e, t + 1);
|
|
220
|
+
throw s;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Schedule flush based on priority
|
|
225
|
+
*/
|
|
226
|
+
scheduleFlush(e) {
|
|
227
|
+
switch (e) {
|
|
228
|
+
case 0:
|
|
229
|
+
this.flush();
|
|
230
|
+
break;
|
|
231
|
+
case 1:
|
|
232
|
+
queueMicrotask(() => this.flush());
|
|
233
|
+
break;
|
|
234
|
+
case 2:
|
|
235
|
+
typeof requestAnimationFrame < "u" ? requestAnimationFrame(() => this.flush()) : queueMicrotask(() => this.flush());
|
|
236
|
+
break;
|
|
237
|
+
case 3:
|
|
238
|
+
case 4:
|
|
239
|
+
typeof requestIdleCallback < "u" ? requestIdleCallback(() => this.flush(), { timeout: 1e3 }) : setTimeout(() => this.flush(), 50);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Check if there's higher priority work waiting
|
|
245
|
+
*/
|
|
246
|
+
hasHigherPriorityWork(e) {
|
|
247
|
+
for (let t = 0; t < e; t++) {
|
|
248
|
+
const s = this.updateQueues.get(t);
|
|
249
|
+
if (s && s.size > 0)
|
|
250
|
+
return !0;
|
|
251
|
+
}
|
|
252
|
+
return !1;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get queue for priority level
|
|
256
|
+
*/
|
|
257
|
+
getQueue(e) {
|
|
258
|
+
const t = this.updateQueues.get(e);
|
|
259
|
+
if (!t)
|
|
260
|
+
throw new Error(`Invalid priority level: ${e}`);
|
|
261
|
+
return t;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Register error handler
|
|
265
|
+
*/
|
|
266
|
+
onError(e) {
|
|
267
|
+
return this.errorHandlers.add(e), () => this.errorHandlers.delete(e);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Handle reactive errors with recovery
|
|
271
|
+
*/
|
|
272
|
+
handleReactiveError(e) {
|
|
273
|
+
this.errorCount++;
|
|
274
|
+
let t = !1;
|
|
275
|
+
for (const s of this.errorHandlers)
|
|
276
|
+
try {
|
|
277
|
+
s(e), t = !0;
|
|
278
|
+
} catch (r) {
|
|
279
|
+
console.error("Error handler threw error:", r);
|
|
280
|
+
}
|
|
281
|
+
if (!t && (console.error("Unhandled reactive error:", e), process.env.NODE_ENV === "development"))
|
|
282
|
+
throw e;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Get performance metrics
|
|
286
|
+
*/
|
|
287
|
+
getPerformanceMetrics() {
|
|
288
|
+
let e = 0;
|
|
289
|
+
for (const t of this.updateQueues.values())
|
|
290
|
+
e += t.size;
|
|
291
|
+
return {
|
|
292
|
+
totalNodes: e,
|
|
293
|
+
updateCycles: this.totalUpdateCycles,
|
|
294
|
+
averageUpdateTime: this.totalUpdateCycles > 0 ? this.totalUpdateTime / this.totalUpdateCycles : 0,
|
|
295
|
+
memoryUsage: this.estimateMemoryUsage(),
|
|
296
|
+
errorCount: this.errorCount
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Estimate memory usage (rough approximation)
|
|
301
|
+
*/
|
|
302
|
+
estimateMemoryUsage() {
|
|
303
|
+
let e = 0;
|
|
304
|
+
for (const t of this.updateQueues.values())
|
|
305
|
+
e += t.size * 50;
|
|
306
|
+
return e += this.errorHandlers.size * 100, e;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Check if node is scheduled
|
|
310
|
+
*/
|
|
311
|
+
hasNode(e) {
|
|
312
|
+
for (const t of this.updateQueues.values())
|
|
313
|
+
if (t.has(e))
|
|
314
|
+
return !0;
|
|
315
|
+
return !1;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Flush all pending updates synchronously
|
|
319
|
+
*/
|
|
320
|
+
flushSync() {
|
|
321
|
+
this.isFlushPending && (this.isFlushPending = !1, this.flush());
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Clear all pending updates
|
|
325
|
+
*/
|
|
326
|
+
clearPending() {
|
|
327
|
+
for (const e of this.updateQueues.values())
|
|
328
|
+
e.clear();
|
|
329
|
+
this.isFlushPending = !1;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Cleanup all reactive nodes and destroy scheduler
|
|
333
|
+
*/
|
|
334
|
+
destroy() {
|
|
335
|
+
this.isDestroyed = !0;
|
|
336
|
+
for (const e of this.updateQueues.values()) {
|
|
337
|
+
for (const t of e)
|
|
338
|
+
try {
|
|
339
|
+
t.cleanup();
|
|
340
|
+
} catch (s) {
|
|
341
|
+
console.error("Error cleaning up reactive node:", s);
|
|
342
|
+
}
|
|
343
|
+
e.clear();
|
|
344
|
+
}
|
|
345
|
+
this.updateQueues.clear(), this.errorHandlers.clear(), $.instance = null;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get debug information
|
|
349
|
+
*/
|
|
350
|
+
getDebugInfo() {
|
|
351
|
+
const e = {};
|
|
352
|
+
for (const [t, s] of this.updateQueues)
|
|
353
|
+
e[_[t]] = s.size;
|
|
354
|
+
return {
|
|
355
|
+
isFlushPending: this.isFlushPending,
|
|
356
|
+
isDestroyed: this.isDestroyed,
|
|
357
|
+
queueSizes: e,
|
|
358
|
+
errorHandlerCount: this.errorHandlers.size,
|
|
359
|
+
performance: this.getPerformanceMetrics()
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
S(xe, "instance", null);
|
|
364
|
+
var $e = Object.defineProperty, Oe = (n, e, t) => e in n ? $e(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, x = (n, e, t) => Oe(n, typeof e != "symbol" ? e + "" : e, t);
|
|
365
|
+
let Re = class extends oe {
|
|
366
|
+
constructor(e, t = {}, s = ne()) {
|
|
367
|
+
super(e, s), x(this, "type", "computed"), x(this, "priority"), x(this, "_hasValue", !1), x(this, "_error", null), x(this, "equalsFn"), x(this, "options"), this.priority = t.priority ?? _.Normal, this.equalsFn = t.equals ?? Ae, this.options = t;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Get the computed value, tracking dependency and lazily computing
|
|
371
|
+
*/
|
|
372
|
+
getValue() {
|
|
373
|
+
const e = ie();
|
|
374
|
+
return e && e.state !== g.Disposed && (this.observers.add(e), e.sources.add(this)), (this.state === g.Dirty || !this._hasValue) && (this.execute(), this._hasValue = !0), this.value;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get the current value without tracking dependency
|
|
378
|
+
*/
|
|
379
|
+
peek() {
|
|
380
|
+
return (this.state === g.Dirty || !this._hasValue) && (this.execute(), this._hasValue = !0), this.value;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Remove an observer (cleanup)
|
|
384
|
+
*/
|
|
385
|
+
removeObserver(e) {
|
|
386
|
+
this.observers.delete(e), this.options.releaseOnNoObservers === !0 && this.observers.size === 0 && e.state === g.Disposed && this.releaseSources();
|
|
387
|
+
}
|
|
388
|
+
releaseSources() {
|
|
389
|
+
for (const e of this.sources)
|
|
390
|
+
"removeObserver" in e && e.removeObserver(this);
|
|
391
|
+
this.sources.clear(), this._hasValue = !1, this.state = g.Dirty;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Execute the computation and notify observers
|
|
395
|
+
*/
|
|
396
|
+
execute() {
|
|
397
|
+
const e = this._hasValue ? this.value : void 0, t = super.execute();
|
|
398
|
+
if (!this._hasValue || !this.equalsFn(e, t))
|
|
399
|
+
for (const s of this.observers)
|
|
400
|
+
s.state !== g.Disposed && (s.state = g.Dirty, "execute" in s && typeof s.execute == "function" && queueMicrotask(() => {
|
|
401
|
+
s.state === g.Dirty && s.execute();
|
|
402
|
+
}));
|
|
403
|
+
return t;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Notify method for ReactiveNode compatibility
|
|
407
|
+
*/
|
|
408
|
+
notify() {
|
|
409
|
+
this.execute();
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Complete cleanup for memory management
|
|
413
|
+
*/
|
|
414
|
+
cleanup() {
|
|
415
|
+
for (const e of this.sources)
|
|
416
|
+
"removeObserver" in e && e.removeObserver(this);
|
|
417
|
+
this.sources.clear();
|
|
418
|
+
for (const e of this.observers)
|
|
419
|
+
e.sources.delete(this);
|
|
420
|
+
this.observers.clear(), this._hasValue = !1, this._error = null, this.state = g.Disposed;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Dispose the computed value
|
|
424
|
+
*/
|
|
425
|
+
dispose() {
|
|
426
|
+
this.cleanup(), super.dispose();
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Debug information
|
|
430
|
+
*/
|
|
431
|
+
[Symbol.for("tachui.debug")]() {
|
|
432
|
+
return {
|
|
433
|
+
id: this.id,
|
|
434
|
+
type: this.type,
|
|
435
|
+
value: this._hasValue ? this.value : void 0,
|
|
436
|
+
hasValue: this._hasValue,
|
|
437
|
+
error: this._error?.message,
|
|
438
|
+
state: this.state,
|
|
439
|
+
sourceCount: this.sources.size,
|
|
440
|
+
observerCount: this.observers.size,
|
|
441
|
+
priority: _[this.priority],
|
|
442
|
+
debugName: this.options.debugName,
|
|
443
|
+
equalsFn: this.equalsFn.name || "anonymous"
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
toString() {
|
|
447
|
+
return `Computed(${this.options.debugName || this.id}): ${this._hasValue ? this.value : "no value"}`;
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
function Te(n, e) {
|
|
451
|
+
const t = new Re(n, e), s = t.getValue.bind(t);
|
|
452
|
+
return s.peek = t.peek.bind(t), Object.defineProperty(s, Symbol.for("tachui.computed"), {
|
|
453
|
+
value: t,
|
|
454
|
+
enumerable: !1
|
|
455
|
+
}), s;
|
|
456
|
+
}
|
|
457
|
+
function P(n) {
|
|
458
|
+
return typeof n == "function" && Symbol.for("tachui.computed") in n;
|
|
459
|
+
}
|
|
460
|
+
const [Pe, Tt] = G("light");
|
|
461
|
+
Te(() => {
|
|
462
|
+
const n = Pe();
|
|
463
|
+
return n === "system" ? Le() : n;
|
|
464
|
+
});
|
|
465
|
+
function Le() {
|
|
466
|
+
return typeof window < "u" && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
467
|
+
}
|
|
468
|
+
typeof globalThis.__DEV__ > "u" && (globalThis.__DEV__ = process.env.NODE_ENV !== "production");
|
|
469
|
+
var ke = Object.defineProperty, ze = (n, e, t) => e in n ? ke(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, ee = (n, e, t) => ze(n, typeof e != "symbol" ? e + "" : e, t);
|
|
470
|
+
let De = class {
|
|
471
|
+
constructor() {
|
|
472
|
+
ee(this, "pending", /* @__PURE__ */ new Set()), ee(this, "isFlushScheduled", !1);
|
|
473
|
+
}
|
|
474
|
+
schedule(e) {
|
|
475
|
+
this.pending.add(e), this.isFlushScheduled || (this.isFlushScheduled = !0, queueMicrotask(() => this.flush()));
|
|
476
|
+
}
|
|
477
|
+
flush() {
|
|
478
|
+
if (this.pending.size === 0) {
|
|
479
|
+
this.isFlushScheduled = !1;
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
const e = Array.from(this.pending);
|
|
483
|
+
this.pending.clear(), this.isFlushScheduled = !1;
|
|
484
|
+
for (const t of e)
|
|
485
|
+
try {
|
|
486
|
+
t();
|
|
487
|
+
} catch (s) {
|
|
488
|
+
console.error("Error in scheduled task:", s);
|
|
489
|
+
}
|
|
490
|
+
this.pending.size > 0 && (this.isFlushScheduled = !0, queueMicrotask(() => this.flush()));
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
new De();
|
|
494
|
+
let Q = null;
|
|
495
|
+
const y = class y {
|
|
496
|
+
constructor() {
|
|
497
|
+
u(this, "instanceId");
|
|
498
|
+
u(this, "createdAt");
|
|
499
|
+
u(this, "modifiers", /* @__PURE__ */ new Map());
|
|
500
|
+
u(this, "lazyLoaders", /* @__PURE__ */ new Map());
|
|
501
|
+
u(this, "loadingPromises", /* @__PURE__ */ new Map());
|
|
502
|
+
// Feature flags
|
|
503
|
+
u(this, "featureFlags", {
|
|
504
|
+
proxyModifiers: !1,
|
|
505
|
+
// Disabled by default for safe rollout
|
|
506
|
+
autoTypeGeneration: !1,
|
|
507
|
+
hmrCacheInvalidation: !1,
|
|
508
|
+
pluginValidation: !0,
|
|
509
|
+
performanceMonitoring: !1,
|
|
510
|
+
metadataRegistration: !0
|
|
511
|
+
// Enable for new system
|
|
512
|
+
});
|
|
513
|
+
// Metadata storage for type generation
|
|
514
|
+
u(this, "metadata", /* @__PURE__ */ new Map());
|
|
515
|
+
u(this, "metadataHistory", /* @__PURE__ */ new Map());
|
|
516
|
+
u(this, "conflicts", /* @__PURE__ */ new Map());
|
|
517
|
+
// Plugin metadata storage
|
|
518
|
+
u(this, "plugins", /* @__PURE__ */ new Map());
|
|
519
|
+
y.instanceCount++, this.instanceId = Math.random().toString(36).substr(2, 9), this.createdAt = Date.now(), process.env.NODE_ENV === "development" && console.log(
|
|
520
|
+
`🏗️ ModifierRegistry instance created: ${this.instanceId} (total: ${y.instanceCount})`
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
static validateModifierName(e, t = {}) {
|
|
524
|
+
if (y.FORBIDDEN_NAMES.has(e))
|
|
525
|
+
throw new Error(
|
|
526
|
+
`Security Error: Cannot register modifier '${e}' (forbidden name)`
|
|
527
|
+
);
|
|
528
|
+
if (!y.NAME_PATTERN.test(e)) {
|
|
529
|
+
if (t.strict)
|
|
530
|
+
throw new Error(
|
|
531
|
+
`Invalid modifier name '${e}'. Modifier names must match ${y.NAME_PATTERN}`
|
|
532
|
+
);
|
|
533
|
+
process.env.NODE_ENV !== "production" && console.warn(
|
|
534
|
+
`⚠️ Modifier name '${e}' does not match ${y.NAME_PATTERN}. Prefer alphanumeric names for best tooling support.`
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
register(e, t) {
|
|
539
|
+
y.validateModifierName(e), this.modifiers.set(e, t), this.lazyLoaders.delete(e), this.loadingPromises.delete(e);
|
|
540
|
+
}
|
|
541
|
+
registerLazy(e, t) {
|
|
542
|
+
if (y.validateModifierName(e), this.modifiers.has(e)) {
|
|
543
|
+
process.env.NODE_ENV === "development" && console.warn(
|
|
544
|
+
`⚠️ Modifier '${e}' already registered, skipping lazy registration`
|
|
545
|
+
);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
this.lazyLoaders.set(e, t);
|
|
549
|
+
}
|
|
550
|
+
get(e, t) {
|
|
551
|
+
const s = this.modifiers.get(e);
|
|
552
|
+
if (s)
|
|
553
|
+
return s;
|
|
554
|
+
const r = this.lazyLoaders.get(e);
|
|
555
|
+
if (!r) {
|
|
556
|
+
process.env.NODE_ENV === "development" && console.warn(
|
|
557
|
+
`⚠️ Modifier '${e}' not found in registry ${this.instanceId}`
|
|
558
|
+
);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
if (t?.async)
|
|
562
|
+
return this.getAsync(e);
|
|
563
|
+
try {
|
|
564
|
+
const i = r();
|
|
565
|
+
return i instanceof Promise ? i.then((o) => (this.modifiers.set(e, o), this.lazyLoaders.delete(e), o)).catch((o) => {
|
|
566
|
+
process.env.NODE_ENV === "development" && console.warn(`⚠️ Failed to load modifier '${e}':`, o);
|
|
567
|
+
}) : (this.modifiers.set(e, i), this.lazyLoaders.delete(e), i);
|
|
568
|
+
} catch (i) {
|
|
569
|
+
process.env.NODE_ENV === "development" && console.warn(
|
|
570
|
+
`⚠️ Failed to load modifier '${e}' synchronously:`,
|
|
571
|
+
i
|
|
572
|
+
);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
async getAsync(e) {
|
|
577
|
+
const t = this.loadingPromises.get(e);
|
|
578
|
+
if (t)
|
|
579
|
+
return t;
|
|
580
|
+
const s = this.lazyLoaders.get(e);
|
|
581
|
+
if (!s)
|
|
582
|
+
return;
|
|
583
|
+
const r = this.loadModifier(e, s);
|
|
584
|
+
this.loadingPromises.set(e, r);
|
|
585
|
+
try {
|
|
586
|
+
const i = await r;
|
|
587
|
+
return this.loadingPromises.delete(e), i;
|
|
588
|
+
} catch (i) {
|
|
589
|
+
throw this.loadingPromises.delete(e), process.env.NODE_ENV === "development" && console.error(`❌ Failed to load modifier '${e}':`, i), i;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
async loadModifier(e, t) {
|
|
593
|
+
try {
|
|
594
|
+
const s = await t();
|
|
595
|
+
return this.modifiers.set(e, s), this.lazyLoaders.delete(e), s;
|
|
596
|
+
} catch (s) {
|
|
597
|
+
throw process.env.NODE_ENV === "development" && console.error(`❌ Error loading modifier '${e}':`, s), s;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
has(e) {
|
|
601
|
+
return this.modifiers.has(e) || this.lazyLoaders.has(e);
|
|
602
|
+
}
|
|
603
|
+
list() {
|
|
604
|
+
const e = Array.from(this.modifiers.keys()), t = Array.from(this.lazyLoaders.keys());
|
|
605
|
+
return [...e, ...t];
|
|
606
|
+
}
|
|
607
|
+
clear() {
|
|
608
|
+
this.modifiers.clear(), this.lazyLoaders.clear(), this.loadingPromises.clear(), this.metadata.clear(), this.metadataHistory.clear(), this.conflicts.clear(), this.plugins.clear(), process.env.NODE_ENV === "development" && console.log(
|
|
609
|
+
`🧹 Cleared all modifiers and lazy loaders from registry ${this.instanceId}`
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
reset() {
|
|
613
|
+
this.clear(), process.env.NODE_ENV === "test" && (y.instanceCount = 0);
|
|
614
|
+
}
|
|
615
|
+
validateRegistry() {
|
|
616
|
+
const e = this.list(), t = e.filter(
|
|
617
|
+
(s, r) => e.indexOf(s) !== r
|
|
618
|
+
);
|
|
619
|
+
return {
|
|
620
|
+
totalModifiers: this.modifiers.size + this.lazyLoaders.size,
|
|
621
|
+
duplicateNames: t,
|
|
622
|
+
orphanedReferences: [],
|
|
623
|
+
// Could be enhanced to scan for broken references
|
|
624
|
+
instanceId: this.instanceId,
|
|
625
|
+
createdAt: this.createdAt,
|
|
626
|
+
instanceCount: y.instanceCount
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Get diagnostic information about this registry instance
|
|
631
|
+
*/
|
|
632
|
+
getDiagnostics() {
|
|
633
|
+
return {
|
|
634
|
+
instanceId: this.instanceId,
|
|
635
|
+
createdAt: this.createdAt,
|
|
636
|
+
modifierCount: this.modifiers.size,
|
|
637
|
+
lazyLoaderCount: this.lazyLoaders.size,
|
|
638
|
+
modifiers: this.list(),
|
|
639
|
+
loadedModifiers: Array.from(this.modifiers.keys()),
|
|
640
|
+
lazyModifiers: Array.from(this.lazyLoaders.keys()),
|
|
641
|
+
featureFlags: this.featureFlags,
|
|
642
|
+
metadataCount: this.metadata.size
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
// ============================================================================
|
|
646
|
+
// Feature Flag Methods
|
|
647
|
+
// ============================================================================
|
|
648
|
+
/**
|
|
649
|
+
* Set feature flags for the registry
|
|
650
|
+
* Allows enabling/disabling features for gradual rollout
|
|
651
|
+
*/
|
|
652
|
+
setFeatureFlags(e) {
|
|
653
|
+
this.featureFlags = {
|
|
654
|
+
...this.featureFlags,
|
|
655
|
+
...e
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Get current feature flags
|
|
660
|
+
*/
|
|
661
|
+
getFeatureFlags() {
|
|
662
|
+
return { ...this.featureFlags };
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Check if a specific feature is enabled
|
|
666
|
+
*/
|
|
667
|
+
isFeatureEnabled(e) {
|
|
668
|
+
return this.featureFlags[e] === !0;
|
|
669
|
+
}
|
|
670
|
+
// ============================================================================
|
|
671
|
+
// Metadata Methods (for build-time type generation)
|
|
672
|
+
// ============================================================================
|
|
673
|
+
/**
|
|
674
|
+
* Register metadata for a modifier (for type generation)
|
|
675
|
+
*/
|
|
676
|
+
registerMetadata(e) {
|
|
677
|
+
if (!this.isFeatureEnabled("metadataRegistration")) {
|
|
678
|
+
process.env.NODE_ENV === "development" && console.warn(
|
|
679
|
+
"⚠️ Metadata registration is disabled. Enable 'metadataRegistration' feature flag."
|
|
680
|
+
);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
if (!e.plugin)
|
|
684
|
+
throw new Error(
|
|
685
|
+
`Modifier metadata '${String(e.name)}' must include a plugin identifier`
|
|
686
|
+
);
|
|
687
|
+
typeof e.name == "string" && y.validateModifierName(e.name, {
|
|
688
|
+
strict: !0
|
|
689
|
+
});
|
|
690
|
+
const t = this.metadata.get(e.name), s = t?.plugin === e.plugin;
|
|
691
|
+
if (this.recordMetadataHistoryEntry(e), !t) {
|
|
692
|
+
this.metadata.set(e.name, e);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
if (s) {
|
|
696
|
+
this.metadata.set(e.name, e);
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
if (e.priority > t.priority) {
|
|
700
|
+
process.env.NODE_ENV === "development" && console.warn(
|
|
701
|
+
`⚠️ Overriding modifier metadata '${String(e.name)}' from ${t.plugin} (priority ${t.priority}) with ${e.plugin} (priority ${e.priority})`
|
|
702
|
+
), this.metadata.set(e.name, e);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
e.priority === t.priority && e.plugin !== t.plugin && process.env.NODE_ENV === "development" && console.error(
|
|
706
|
+
`❌ Metadata conflict for '${String(e.name)}': ${t.plugin} vs ${e.plugin} (both priority ${e.priority})`
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
recordMetadataHistoryEntry(e) {
|
|
710
|
+
const t = this.metadataHistory.get(e.name) ?? [], s = `${e.plugin}:${e.priority}`, r = t.findIndex(
|
|
711
|
+
(i) => `${i.plugin}:${i.priority}` === s
|
|
712
|
+
);
|
|
713
|
+
r >= 0 ? t[r] = e : t.push(e), this.metadataHistory.set(e.name, t), this.refreshConflictsFor(e.name, t);
|
|
714
|
+
}
|
|
715
|
+
refreshConflictsFor(e, t) {
|
|
716
|
+
const s = [], r = /* @__PURE__ */ new Map();
|
|
717
|
+
for (const i of t) {
|
|
718
|
+
const o = r.get(i.priority) ?? /* @__PURE__ */ new Map();
|
|
719
|
+
o.set(i.plugin, i), r.set(i.priority, o);
|
|
720
|
+
}
|
|
721
|
+
for (const i of r.values())
|
|
722
|
+
if (i.size > 1)
|
|
723
|
+
for (const o of i.values())
|
|
724
|
+
s.push(o);
|
|
725
|
+
s.length > 0 ? this.conflicts.set(e, s) : this.conflicts.delete(e);
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Get metadata for a specific modifier
|
|
729
|
+
*/
|
|
730
|
+
getMetadata(e) {
|
|
731
|
+
return this.metadata.get(e);
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Get all registered metadata
|
|
735
|
+
*/
|
|
736
|
+
getAllMetadata() {
|
|
737
|
+
return Array.from(this.metadata.values());
|
|
738
|
+
}
|
|
739
|
+
/**
|
|
740
|
+
* Get metadata filtered by category
|
|
741
|
+
*/
|
|
742
|
+
getModifiersByCategory(e) {
|
|
743
|
+
return this.getAllMetadata().filter((t) => t.category === e);
|
|
744
|
+
}
|
|
745
|
+
getMetadataByCategory(e) {
|
|
746
|
+
return this.getModifiersByCategory(e);
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Get conflicts (multiple modifiers with same name but different plugins)
|
|
750
|
+
*/
|
|
751
|
+
getConflicts() {
|
|
752
|
+
return new Map(
|
|
753
|
+
Array.from(this.conflicts.entries(), ([e, t]) => [e, [...t]])
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
registerPlugin(e) {
|
|
757
|
+
if (!e.name || !e.version)
|
|
758
|
+
throw new Error("Plugin must define both name and version");
|
|
759
|
+
if (!e.author)
|
|
760
|
+
throw new Error(
|
|
761
|
+
`Plugin '${e.name}' must include an author or organization`
|
|
762
|
+
);
|
|
763
|
+
!e.verified && process.env.NODE_ENV !== "production" && console.warn(
|
|
764
|
+
`⚠️ Registering unverified plugin '${e.name}'. Install plugins from trusted sources.`
|
|
765
|
+
), this.plugins.set(e.name, e);
|
|
766
|
+
}
|
|
767
|
+
getPluginInfo(e) {
|
|
768
|
+
return this.plugins.get(e);
|
|
769
|
+
}
|
|
770
|
+
listPlugins() {
|
|
771
|
+
return Array.from(this.plugins.values());
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
u(y, "instanceCount", 0), u(y, "FORBIDDEN_NAMES", /* @__PURE__ */ new Set([
|
|
775
|
+
"__proto__",
|
|
776
|
+
"constructor",
|
|
777
|
+
"prototype",
|
|
778
|
+
"hasOwnProperty",
|
|
779
|
+
"isPrototypeOf",
|
|
780
|
+
"toString",
|
|
781
|
+
"valueOf"
|
|
782
|
+
])), u(y, "NAME_PATTERN", /^[a-zA-Z_$][a-zA-Z0-9_$]*$/);
|
|
783
|
+
let K = y;
|
|
784
|
+
function _e() {
|
|
785
|
+
return Q || (Q = new K()), Q;
|
|
786
|
+
}
|
|
787
|
+
const te = _e();
|
|
788
|
+
function w(n, e = {}) {
|
|
789
|
+
const t = ne();
|
|
790
|
+
let s;
|
|
791
|
+
const r = () => {
|
|
792
|
+
const o = n(s);
|
|
793
|
+
return s = o, o;
|
|
794
|
+
}, i = new oe(r, t);
|
|
795
|
+
return e.name && Object.defineProperty(i, "name", {
|
|
796
|
+
value: e.name,
|
|
797
|
+
enumerable: !1
|
|
798
|
+
}), i.execute(), i;
|
|
799
|
+
}
|
|
800
|
+
process.env.NODE_ENV === "development" && console.log("📤 Created RegistryAdapter for globalModifierRegistry", {
|
|
801
|
+
registryId: te.instanceId,
|
|
802
|
+
currentSize: te.list().length
|
|
803
|
+
});
|
|
804
|
+
function Ve(n, e, t = {}, s = {}) {
|
|
805
|
+
if (!e.length) return n;
|
|
806
|
+
const r = {
|
|
807
|
+
componentId: t.componentId || "unknown",
|
|
808
|
+
phase: t.phase || "creation",
|
|
809
|
+
...t.element && { element: t.element },
|
|
810
|
+
...t.parentElement && { parentElement: t.parentElement },
|
|
811
|
+
...t.componentInstance && {
|
|
812
|
+
componentInstance: t.componentInstance
|
|
813
|
+
},
|
|
814
|
+
...t.previousModifiers && {
|
|
815
|
+
previousModifiers: t.previousModifiers
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
switch (s.batch ? "batch" : "sequential") {
|
|
819
|
+
case "batch":
|
|
820
|
+
return Fe(n, e, r, s);
|
|
821
|
+
default:
|
|
822
|
+
return He(n, e, r, s);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
function He(n, e, t, s) {
|
|
826
|
+
const r = [...e].sort(
|
|
827
|
+
(h, c) => h.priority - c.priority
|
|
828
|
+
);
|
|
829
|
+
let i = n;
|
|
830
|
+
const o = [], a = [];
|
|
831
|
+
for (const h of r)
|
|
832
|
+
try {
|
|
833
|
+
const c = h.apply(i, t);
|
|
834
|
+
c && typeof c == "object" && "type" in c && (i = c), s.immediate && !s.suppressEffects && (o.forEach((l) => l()), o.length = 0);
|
|
835
|
+
} catch (c) {
|
|
836
|
+
console.error(`Failed to apply modifier ${h.type}:`, c);
|
|
837
|
+
}
|
|
838
|
+
if (a.length > 0) {
|
|
839
|
+
const h = i.dispose;
|
|
840
|
+
i.dispose = () => {
|
|
841
|
+
a.forEach((c) => c()), h && h();
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
return i;
|
|
845
|
+
}
|
|
846
|
+
function Fe(n, e, t, s) {
|
|
847
|
+
const r = Ue(e);
|
|
848
|
+
let i = n;
|
|
849
|
+
const o = [], a = [];
|
|
850
|
+
for (const [h, c] of r)
|
|
851
|
+
try {
|
|
852
|
+
i = je(i, c, t);
|
|
853
|
+
} catch (l) {
|
|
854
|
+
(typeof process > "u" || process.env.NODE_ENV !== "test") && console.error(`Failed to apply modifier group ${h}:`, l);
|
|
855
|
+
}
|
|
856
|
+
if (s.suppressEffects || o.forEach((h) => h()), a.length > 0) {
|
|
857
|
+
const h = i.dispose;
|
|
858
|
+
i.dispose = () => {
|
|
859
|
+
a.forEach((c) => c()), h && h();
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
return i;
|
|
863
|
+
}
|
|
864
|
+
function Ue(n) {
|
|
865
|
+
const e = /* @__PURE__ */ new Map();
|
|
866
|
+
for (const t of n) {
|
|
867
|
+
const s = e.get(t.type) || [];
|
|
868
|
+
s.push(t), e.set(t.type, s);
|
|
869
|
+
}
|
|
870
|
+
return e;
|
|
871
|
+
}
|
|
872
|
+
function je(n, e, t) {
|
|
873
|
+
const s = [...e].sort(
|
|
874
|
+
(i, o) => i.priority - o.priority
|
|
875
|
+
);
|
|
876
|
+
let r = n;
|
|
877
|
+
for (const i of s)
|
|
878
|
+
try {
|
|
879
|
+
const o = i.apply(r, t);
|
|
880
|
+
o && typeof o == "object" && "type" in o && (r = o);
|
|
881
|
+
} catch (o) {
|
|
882
|
+
(typeof process > "u" || process.env.NODE_ENV !== "test") && console.error(`Failed to apply modifier ${i.type}:`, o);
|
|
883
|
+
}
|
|
884
|
+
return r;
|
|
885
|
+
}
|
|
886
|
+
const H = /* @__PURE__ */ new Map([
|
|
887
|
+
["nav", { role: "navigation", applyARIA: !0 }],
|
|
888
|
+
["main", { role: "main", applyARIA: !0 }],
|
|
889
|
+
["article", { role: "article", applyARIA: !0 }],
|
|
890
|
+
["section", { role: "region", applyARIA: !0 }],
|
|
891
|
+
["aside", { role: "complementary", applyARIA: !0 }],
|
|
892
|
+
["header", { role: "banner", applyARIA: !1 }],
|
|
893
|
+
// Context dependent - may not always be page banner
|
|
894
|
+
["footer", { role: "contentinfo", applyARIA: !1 }],
|
|
895
|
+
// Context dependent - may not always be page footer
|
|
896
|
+
["form", { role: "form", applyARIA: !0 }],
|
|
897
|
+
["search", { role: "search", applyARIA: !0 }],
|
|
898
|
+
["dialog", { role: "dialog", applyARIA: !0 }],
|
|
899
|
+
["button", { role: "button", applyARIA: !1 }],
|
|
900
|
+
// Usually implicit
|
|
901
|
+
["a", { role: "link", applyARIA: !1 }]
|
|
902
|
+
// Usually implicit
|
|
903
|
+
]);
|
|
904
|
+
let We = {
|
|
905
|
+
autoApplySemanticRoles: !0,
|
|
906
|
+
warnOnOverrides: process.env.NODE_ENV !== "production",
|
|
907
|
+
warnOnSemanticIssues: process.env.NODE_ENV !== "production",
|
|
908
|
+
validateTags: !0,
|
|
909
|
+
allowInvalidTags: !0
|
|
910
|
+
};
|
|
911
|
+
function Be() {
|
|
912
|
+
return { ...We };
|
|
913
|
+
}
|
|
914
|
+
var Qe = Object.defineProperty, qe = (n, e, t) => e in n ? Qe(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, Ye = (n, e, t) => qe(n, e + "", t);
|
|
915
|
+
const ae = class L {
|
|
916
|
+
static getInstance() {
|
|
917
|
+
return L.instance || (L.instance = new L()), L.instance;
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Apply semantic ARIA attributes to an element based on its tag
|
|
921
|
+
*/
|
|
922
|
+
applySemanticAttributes(e, t, s) {
|
|
923
|
+
const r = Be();
|
|
924
|
+
if (!r.autoApplySemanticRoles) return;
|
|
925
|
+
const i = H.get(t);
|
|
926
|
+
if (!(!i || !i.applyARIA)) {
|
|
927
|
+
if (s?.role) {
|
|
928
|
+
r.warnOnSemanticIssues && process.env.NODE_ENV !== "production" && console.warn(
|
|
929
|
+
`ARIA role '${s.role}' overrides semantic role '${i.role}' for tag '${t}'`
|
|
930
|
+
);
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
if (e.hasAttribute("role")) {
|
|
934
|
+
r.warnOnSemanticIssues && process.env.NODE_ENV !== "production" && console.warn(
|
|
935
|
+
`Existing role attribute overrides semantic role '${i.role}' for tag '${t}'`
|
|
936
|
+
);
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
e.setAttribute("role", i.role);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Get semantic role information for a tag
|
|
944
|
+
*/
|
|
945
|
+
getSemanticRole(e) {
|
|
946
|
+
return H.get(e);
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Check if a tag has automatic ARIA role application enabled
|
|
950
|
+
*/
|
|
951
|
+
hasAutoARIA(e) {
|
|
952
|
+
const t = H.get(e);
|
|
953
|
+
return t ? t.applyARIA : !1;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Get all tags that support automatic ARIA roles
|
|
957
|
+
*/
|
|
958
|
+
getAutoARIATags() {
|
|
959
|
+
return Array.from(H.entries()).filter(([, e]) => e.applyARIA).map(([e]) => e);
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Apply semantic attributes during DOM node creation
|
|
963
|
+
* This is called by the renderer when creating elements
|
|
964
|
+
*/
|
|
965
|
+
processElementNode(e, t, s, r) {
|
|
966
|
+
if (this.applySemanticAttributes(e, t, r), s && process.env.NODE_ENV !== "production") {
|
|
967
|
+
const i = this.getSemanticRole(t);
|
|
968
|
+
i && e.setAttribute(
|
|
969
|
+
"data-tachui-semantic",
|
|
970
|
+
JSON.stringify({
|
|
971
|
+
originalComponent: s.originalType,
|
|
972
|
+
overriddenTo: t,
|
|
973
|
+
semanticRole: i.role,
|
|
974
|
+
autoApplied: i.applyARIA
|
|
975
|
+
})
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
Ye(ae, "instance");
|
|
981
|
+
let Xe = ae;
|
|
982
|
+
const Ge = Xe.getInstance();
|
|
983
|
+
var Ke = Object.defineProperty, Ze = (n, e, t) => e in n ? Ke(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, q = (n, e, t) => Ze(n, typeof e != "symbol" ? e + "" : e, t);
|
|
984
|
+
const Je = /* @__PURE__ */ new Set([
|
|
985
|
+
"click",
|
|
986
|
+
"dblclick",
|
|
987
|
+
"mousedown",
|
|
988
|
+
"mouseup",
|
|
989
|
+
"mouseover",
|
|
990
|
+
"mouseout",
|
|
991
|
+
"mouseenter",
|
|
992
|
+
"mouseleave",
|
|
993
|
+
"focusin",
|
|
994
|
+
// Bubbles, unlike 'focus'
|
|
995
|
+
"focusout",
|
|
996
|
+
// Bubbles, unlike 'blur'
|
|
997
|
+
"input",
|
|
998
|
+
"change",
|
|
999
|
+
"submit",
|
|
1000
|
+
"keydown",
|
|
1001
|
+
"keyup",
|
|
1002
|
+
"keypress"
|
|
1003
|
+
]), se = /* @__PURE__ */ new Set([
|
|
1004
|
+
"scroll",
|
|
1005
|
+
"wheel",
|
|
1006
|
+
"touchstart",
|
|
1007
|
+
"touchmove",
|
|
1008
|
+
"touchend"
|
|
1009
|
+
]);
|
|
1010
|
+
class et {
|
|
1011
|
+
constructor() {
|
|
1012
|
+
q(this, "containerListeners", /* @__PURE__ */ new WeakMap()), q(this, "elementHandlers", /* @__PURE__ */ new WeakMap()), q(this, "handlerCounts", /* @__PURE__ */ new WeakMap());
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Register an event handler with delegation
|
|
1016
|
+
*/
|
|
1017
|
+
register(e, t, s, r) {
|
|
1018
|
+
let i = this.elementHandlers.get(t);
|
|
1019
|
+
i && i.has(s) && this.unregister(e, t, s), i || (i = /* @__PURE__ */ new Map(), this.elementHandlers.set(t, i)), i.set(s, { handler: r, element: t });
|
|
1020
|
+
let o = this.handlerCounts.get(e);
|
|
1021
|
+
o || (o = /* @__PURE__ */ new Map(), this.handlerCounts.set(e, o));
|
|
1022
|
+
const a = o.get(s) || 0;
|
|
1023
|
+
return o.set(s, a + 1), this.ensureRootListener(e, s), () => {
|
|
1024
|
+
this.unregister(e, t, s);
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Unregister an event handler
|
|
1029
|
+
*/
|
|
1030
|
+
unregister(e, t, s) {
|
|
1031
|
+
const r = this.elementHandlers.get(t);
|
|
1032
|
+
r && (r.delete(s), r.size === 0 && this.elementHandlers.delete(t));
|
|
1033
|
+
const i = this.handlerCounts.get(e);
|
|
1034
|
+
if (i) {
|
|
1035
|
+
const o = (i.get(s) || 0) - 1;
|
|
1036
|
+
o <= 0 ? (i.delete(s), this.removeRootListener(e, s)) : i.set(s, o);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Ensure root listener exists for event type on container
|
|
1041
|
+
*/
|
|
1042
|
+
ensureRootListener(e, t) {
|
|
1043
|
+
let s = this.containerListeners.get(e);
|
|
1044
|
+
if (s || (s = /* @__PURE__ */ new Map(), this.containerListeners.set(e, s)), s.has(t))
|
|
1045
|
+
return;
|
|
1046
|
+
const r = (o) => {
|
|
1047
|
+
this.handleDelegatedEvent(e, t, o);
|
|
1048
|
+
}, i = se.has(t) ? { passive: !0 } : { passive: !1 };
|
|
1049
|
+
e.addEventListener(t, r, i), s.set(t, r);
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Remove root listener for event type on container
|
|
1053
|
+
*/
|
|
1054
|
+
removeRootListener(e, t) {
|
|
1055
|
+
const s = this.containerListeners.get(e);
|
|
1056
|
+
if (!s) return;
|
|
1057
|
+
const r = s.get(t);
|
|
1058
|
+
r && (e.removeEventListener(t, r), s.delete(t));
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Handle delegated event by finding target handler
|
|
1062
|
+
*/
|
|
1063
|
+
handleDelegatedEvent(e, t, s) {
|
|
1064
|
+
const r = s.target;
|
|
1065
|
+
if (!r) return;
|
|
1066
|
+
let i = r;
|
|
1067
|
+
for (; i && i !== e; ) {
|
|
1068
|
+
const o = this.elementHandlers.get(i);
|
|
1069
|
+
if (o) {
|
|
1070
|
+
const a = o.get(t);
|
|
1071
|
+
if (a) {
|
|
1072
|
+
try {
|
|
1073
|
+
a.handler(s);
|
|
1074
|
+
} catch (h) {
|
|
1075
|
+
console.error(`Delegated event handler error for ${t}:`, h);
|
|
1076
|
+
}
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
i = i.parentElement;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Check if event type should use delegation
|
|
1085
|
+
*/
|
|
1086
|
+
shouldDelegate(e) {
|
|
1087
|
+
return Je.has(e);
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Check if event type should use passive listeners
|
|
1091
|
+
*/
|
|
1092
|
+
shouldBePassive(e) {
|
|
1093
|
+
return se.has(e);
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Get metrics for debugging
|
|
1097
|
+
*/
|
|
1098
|
+
getMetrics(e) {
|
|
1099
|
+
const t = this.handlerCounts.get(e);
|
|
1100
|
+
if (!t)
|
|
1101
|
+
return { eventTypes: [], totalHandlers: 0, handlersPerType: {} };
|
|
1102
|
+
const s = {};
|
|
1103
|
+
let r = 0;
|
|
1104
|
+
return t.forEach((i, o) => {
|
|
1105
|
+
s[o] = i, r += i;
|
|
1106
|
+
}), {
|
|
1107
|
+
eventTypes: Array.from(t.keys()),
|
|
1108
|
+
totalHandlers: r,
|
|
1109
|
+
handlersPerType: s
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Cleanup all handlers for a container
|
|
1114
|
+
*/
|
|
1115
|
+
cleanupContainer(e) {
|
|
1116
|
+
const t = this.containerListeners.get(e);
|
|
1117
|
+
t && (t.forEach((s, r) => {
|
|
1118
|
+
e.removeEventListener(r, s);
|
|
1119
|
+
}), this.containerListeners.delete(e)), this.handlerCounts.delete(e);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
const Y = new et();
|
|
1123
|
+
var tt = Object.defineProperty, st = (n, e, t) => e in n ? tt(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, R = (n, e, t) => st(n, typeof e != "symbol" ? e + "" : e, t);
|
|
1124
|
+
class le {
|
|
1125
|
+
constructor() {
|
|
1126
|
+
R(this, "nodeMap", /* @__PURE__ */ new WeakMap()), R(this, "cleanupMap", /* @__PURE__ */ new WeakMap()), R(this, "renderedNodes", /* @__PURE__ */ new Set()), R(this, "elementToContainer", /* @__PURE__ */ new WeakMap()), R(this, "metrics", {
|
|
1127
|
+
created: 0,
|
|
1128
|
+
adopted: 0,
|
|
1129
|
+
removed: 0,
|
|
1130
|
+
inserted: 0,
|
|
1131
|
+
moved: 0,
|
|
1132
|
+
cacheHits: 0,
|
|
1133
|
+
cacheMisses: 0,
|
|
1134
|
+
attributeWrites: 0,
|
|
1135
|
+
attributeRemovals: 0,
|
|
1136
|
+
textUpdates: 0,
|
|
1137
|
+
modifierApplications: 0
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Render a DOM node to an actual DOM element
|
|
1142
|
+
*/
|
|
1143
|
+
render(e, t) {
|
|
1144
|
+
return Array.isArray(e) ? this.renderFragment(e, t) : this.renderSingle(e, t);
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Check if a DOM node has been rendered and tracked.
|
|
1148
|
+
*/
|
|
1149
|
+
hasNode(e) {
|
|
1150
|
+
return this.nodeMap.has(e);
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Get the rendered DOM element associated with a node.
|
|
1154
|
+
*/
|
|
1155
|
+
getRenderedNode(e) {
|
|
1156
|
+
return this.nodeMap.get(e);
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Render a single DOM node
|
|
1160
|
+
*/
|
|
1161
|
+
renderSingle(e, t) {
|
|
1162
|
+
this.renderedNodes.add(e);
|
|
1163
|
+
let s;
|
|
1164
|
+
switch (e.type) {
|
|
1165
|
+
case "element":
|
|
1166
|
+
s = this.createOrUpdateElement(e, t);
|
|
1167
|
+
break;
|
|
1168
|
+
case "text":
|
|
1169
|
+
s = this.createOrUpdateTextNode(e);
|
|
1170
|
+
break;
|
|
1171
|
+
case "comment":
|
|
1172
|
+
s = this.createComment(e), this.metrics.created++;
|
|
1173
|
+
break;
|
|
1174
|
+
default:
|
|
1175
|
+
throw new Error(`Unknown node type: ${e.type}`);
|
|
1176
|
+
}
|
|
1177
|
+
if (this.nodeMap.set(e, s), e.element = s, s instanceof Element && t && this.elementToContainer.set(s, t), s instanceof Element) {
|
|
1178
|
+
let r = [];
|
|
1179
|
+
"modifiers" in e && Array.isArray(e.modifiers) && e.modifiers.length > 0 && (r = e.modifiers), "componentMetadata" in e && e.componentMetadata?.modifiers && Array.isArray(e.componentMetadata.modifiers) && e.componentMetadata.modifiers.length > 0 && (r = e.componentMetadata.modifiers), r.length > 0 && this.applyModifiersToElement(s, r, e);
|
|
1180
|
+
}
|
|
1181
|
+
return e.dispose && this.addCleanup(s, e.dispose), t && this.appendNode(t, s), s;
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Render multiple nodes as a document fragment
|
|
1185
|
+
*/
|
|
1186
|
+
renderFragment(e, t) {
|
|
1187
|
+
const s = document.createDocumentFragment();
|
|
1188
|
+
return e.forEach((r) => {
|
|
1189
|
+
const i = this.renderSingle(r);
|
|
1190
|
+
s.appendChild(i);
|
|
1191
|
+
}), t && (t.appendChild(s), this.metrics.inserted += e.length), s;
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Create a DOM element with props and children
|
|
1195
|
+
*/
|
|
1196
|
+
createOrUpdateElement(e, t) {
|
|
1197
|
+
if (!e.tag)
|
|
1198
|
+
throw new Error("Element node must have a tag");
|
|
1199
|
+
if (e.element && e.element instanceof Element) {
|
|
1200
|
+
const r = e.element;
|
|
1201
|
+
return t && this.elementToContainer.set(r, t), this.updateProps(r, e, t), this.updateChildren(r, e), r;
|
|
1202
|
+
}
|
|
1203
|
+
const s = document.createElement(e.tag);
|
|
1204
|
+
return this.metrics.created++, t && this.elementToContainer.set(s, t), this.applyDebugAttributes(s, e), this.updateProps(s, e, t), this.updateChildren(s, e), s;
|
|
1205
|
+
}
|
|
1206
|
+
updateProps(e, t, s) {
|
|
1207
|
+
const r = t.props || {}, i = t.__appliedProps || {};
|
|
1208
|
+
if (Object.keys(i).forEach((o) => {
|
|
1209
|
+
if (!(o in r)) {
|
|
1210
|
+
if (o === "key" || o === "children" || o.startsWith("on"))
|
|
1211
|
+
return;
|
|
1212
|
+
this.setElementProp(e, o, void 0);
|
|
1213
|
+
}
|
|
1214
|
+
}), Object.entries(r).forEach(([o, a]) => {
|
|
1215
|
+
o === "key" || o === "children" || i && i[o] === a || this.applyProp(e, o, a, s);
|
|
1216
|
+
}), t.__appliedProps = { ...r }, "componentMetadata" in t && t.componentMetadata) {
|
|
1217
|
+
const o = t.componentMetadata;
|
|
1218
|
+
if (o.overriddenTo && o.originalType && t.tag)
|
|
1219
|
+
try {
|
|
1220
|
+
Ge.processElementNode(
|
|
1221
|
+
e,
|
|
1222
|
+
t.tag,
|
|
1223
|
+
o,
|
|
1224
|
+
r?.aria || void 0
|
|
1225
|
+
);
|
|
1226
|
+
} catch (a) {
|
|
1227
|
+
console.warn("[tachUI] Could not process semantic attributes:", a);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
updateChildren(e, t) {
|
|
1232
|
+
const s = t.__renderedChildren || [], r = t.children || [], i = this.elementToContainer.get(e), o = typeof process < "u" && process.env?.TACHUI_DEBUG_PHASE1B === "1";
|
|
1233
|
+
if (s.length === r.length && s.length > 0 && s.every((l, d) => l === r[d])) {
|
|
1234
|
+
r.forEach((l) => {
|
|
1235
|
+
this.updateExistingNode(l);
|
|
1236
|
+
}), t.__renderedChildren = r;
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
if (s.length === 0) {
|
|
1240
|
+
r.forEach((l) => {
|
|
1241
|
+
if (!l || l.type == null) return;
|
|
1242
|
+
const d = this.renderSingle(l, i);
|
|
1243
|
+
this.appendNode(e, d);
|
|
1244
|
+
}), t.__renderedChildren = r;
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
const a = /* @__PURE__ */ new Map(), h = [];
|
|
1248
|
+
s.forEach((l) => {
|
|
1249
|
+
l.key != null ? a.set(l.key, l) : h.push(l);
|
|
1250
|
+
});
|
|
1251
|
+
const c = Array.from({ length: r.length });
|
|
1252
|
+
if (r.forEach((l, d) => {
|
|
1253
|
+
let f;
|
|
1254
|
+
l.key != null ? (f = a.get(l.key), f && a.delete(l.key)) : h.length > 0 && (f = h.shift()), f && this.adoptNode(f, l);
|
|
1255
|
+
const p = this.renderSingle(l, i);
|
|
1256
|
+
c[d] = p;
|
|
1257
|
+
}), o && t.tag) {
|
|
1258
|
+
const l = r.map((p) => p.key ?? null), d = s.map((p) => p.key ?? null), f = c.map(
|
|
1259
|
+
(p) => p && "getAttribute" in p ? p.getAttribute("data-id") : null
|
|
1260
|
+
);
|
|
1261
|
+
console.log("[diff] state", {
|
|
1262
|
+
parent: t.tag,
|
|
1263
|
+
prev: d,
|
|
1264
|
+
next: l,
|
|
1265
|
+
dom: f
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
if (a.forEach((l) => {
|
|
1269
|
+
this.removeNode(l);
|
|
1270
|
+
}), h.forEach((l) => {
|
|
1271
|
+
this.removeNode(l);
|
|
1272
|
+
}), typeof e.insertBefore == "function" && typeof e.appendChild == "function") {
|
|
1273
|
+
let l = null;
|
|
1274
|
+
for (let d = c.length - 1; d >= 0; d--) {
|
|
1275
|
+
const f = c[d];
|
|
1276
|
+
f && (this.insertNode(e, f, l), l = f);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
t.__renderedChildren = r;
|
|
1280
|
+
}
|
|
1281
|
+
updateExistingNode(e) {
|
|
1282
|
+
if (e.type === "element" && e.element instanceof Element) {
|
|
1283
|
+
const t = this.elementToContainer.get(e.element);
|
|
1284
|
+
this.updateProps(e.element, e, t), this.updateChildren(e.element, e);
|
|
1285
|
+
} else e.type === "text" && e.element instanceof Text && e.element.textContent !== e.text && (e.element.textContent = e.text || "", this.recordTextUpdate());
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Apply debug attributes to DOM element if debug mode is enabled
|
|
1289
|
+
*/
|
|
1290
|
+
applyDebugAttributes(e, t) {
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Create or update a text node
|
|
1294
|
+
*/
|
|
1295
|
+
createOrUpdateTextNode(e) {
|
|
1296
|
+
if (e.element && e.element instanceof Text) {
|
|
1297
|
+
const t = e.element;
|
|
1298
|
+
if (t.textContent !== e.text && (t.textContent = e.text || "", this.recordTextUpdate()), e.reactiveContent && !e.dispose) {
|
|
1299
|
+
const s = e.reactiveContent, r = w(() => {
|
|
1300
|
+
try {
|
|
1301
|
+
const i = s();
|
|
1302
|
+
e.text = String(i);
|
|
1303
|
+
const o = t.parentElement;
|
|
1304
|
+
if (o && o.__tachui_asHTML)
|
|
1305
|
+
return;
|
|
1306
|
+
t.textContent = e.text, this.recordTextUpdate();
|
|
1307
|
+
} catch (i) {
|
|
1308
|
+
console.error("createOrUpdateTextNode() reactive effect error:", i);
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
e.dispose = () => {
|
|
1312
|
+
r.dispose();
|
|
1313
|
+
};
|
|
1314
|
+
}
|
|
1315
|
+
return t;
|
|
1316
|
+
}
|
|
1317
|
+
return this.createTextNode(e);
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Create a text node
|
|
1321
|
+
*/
|
|
1322
|
+
createTextNode(e) {
|
|
1323
|
+
const t = document.createTextNode(e.text || "");
|
|
1324
|
+
if (this.metrics.created++, this.recordTextUpdate(), e.reactiveContent) {
|
|
1325
|
+
const s = e.reactiveContent, r = w(() => {
|
|
1326
|
+
try {
|
|
1327
|
+
const i = s();
|
|
1328
|
+
e.text = String(i);
|
|
1329
|
+
const o = t.parentElement;
|
|
1330
|
+
if (o && o.__tachui_asHTML)
|
|
1331
|
+
return;
|
|
1332
|
+
t.textContent = e.text, this.recordTextUpdate();
|
|
1333
|
+
} catch (i) {
|
|
1334
|
+
console.error("createTextNode() reactive effect error:", i);
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
e.dispose = () => {
|
|
1338
|
+
r.dispose();
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
return t;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Create a comment node
|
|
1345
|
+
*/
|
|
1346
|
+
createComment(e) {
|
|
1347
|
+
return this.metrics.created++, document.createComment(e.text || "");
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Apply props to a DOM element with reactive updates
|
|
1351
|
+
*/
|
|
1352
|
+
applyProps(e, t) {
|
|
1353
|
+
Object.entries(t).forEach(([s, r]) => {
|
|
1354
|
+
this.applyProp(e, s, r);
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Apply a single prop to an element
|
|
1359
|
+
*/
|
|
1360
|
+
applyProp(e, t, s, r) {
|
|
1361
|
+
if (t === "className" || t === "class") {
|
|
1362
|
+
this.applyClassName(e, s);
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
if (t === "style") {
|
|
1366
|
+
this.applyStyle(e, s);
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
if (t.startsWith("on") && typeof s == "function") {
|
|
1370
|
+
this.applyEventListener(e, t, s, r);
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
if (T(s) || P(s)) {
|
|
1374
|
+
const i = w(() => {
|
|
1375
|
+
const o = s();
|
|
1376
|
+
this.setElementProp(e, t, o);
|
|
1377
|
+
});
|
|
1378
|
+
this.addCleanup(e, () => {
|
|
1379
|
+
i.dispose();
|
|
1380
|
+
});
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
this.setElementProp(e, t, s);
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Set a property on an element
|
|
1387
|
+
*/
|
|
1388
|
+
setElementProp(e, t, s) {
|
|
1389
|
+
if (s == null) {
|
|
1390
|
+
e.hasAttribute(t) && (e.removeAttribute(t), this.recordAttributeRemoval());
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
const r = e;
|
|
1394
|
+
if ((t === "value" || t === "checked" || t === "disabled") && t in r) {
|
|
1395
|
+
r[t] !== s && (r[t] = s, this.recordAttributeWrite());
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
if (typeof s == "boolean") {
|
|
1399
|
+
s ? e.hasAttribute(t) || (e.setAttribute(t, ""), this.recordAttributeWrite()) : e.hasAttribute(t) ? (e.removeAttribute(t), this.recordAttributeRemoval()) : e.removeAttribute(t);
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
const i = e.getAttribute(t), o = String(s);
|
|
1403
|
+
i !== o && (e.setAttribute(t, o), this.recordAttributeWrite());
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Apply className with reactive updates
|
|
1407
|
+
*/
|
|
1408
|
+
applyClassName(e, t) {
|
|
1409
|
+
if (T(t) || P(t)) {
|
|
1410
|
+
const s = w(() => {
|
|
1411
|
+
const r = t(), i = this.normalizeClassName(r);
|
|
1412
|
+
e.className !== i && (e.className = i, this.recordAttributeWrite());
|
|
1413
|
+
});
|
|
1414
|
+
this.addCleanup(e, () => {
|
|
1415
|
+
s.dispose();
|
|
1416
|
+
});
|
|
1417
|
+
} else {
|
|
1418
|
+
const s = this.normalizeClassName(t);
|
|
1419
|
+
e.className !== s && (e.className = s, this.recordAttributeWrite());
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* Normalize className value
|
|
1424
|
+
*/
|
|
1425
|
+
normalizeClassName(e) {
|
|
1426
|
+
return Array.isArray(e) ? e.filter(Boolean).join(" ") : typeof e == "object" && e !== null ? Object.entries(e).filter(([, t]) => !!t).map(([t]) => t).join(" ") : String(e || "");
|
|
1427
|
+
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Apply styles with reactive updates
|
|
1430
|
+
*/
|
|
1431
|
+
applyStyle(e, t) {
|
|
1432
|
+
const s = e;
|
|
1433
|
+
if (T(t) || P(t)) {
|
|
1434
|
+
const r = w(() => {
|
|
1435
|
+
const i = t();
|
|
1436
|
+
this.setElementStyles(s, i);
|
|
1437
|
+
});
|
|
1438
|
+
this.addCleanup(e, () => {
|
|
1439
|
+
r.dispose();
|
|
1440
|
+
});
|
|
1441
|
+
} else
|
|
1442
|
+
this.setElementStyles(s, t);
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Set styles on an element
|
|
1446
|
+
*/
|
|
1447
|
+
setElementStyles(e, t) {
|
|
1448
|
+
if (typeof t == "string") {
|
|
1449
|
+
e.style.cssText !== t && (e.style.cssText = t, this.recordAttributeWrite());
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
if (typeof t == "object" && t !== null) {
|
|
1453
|
+
const s = e.__appliedStyles || {};
|
|
1454
|
+
Object.keys(s).forEach((r) => {
|
|
1455
|
+
r in t || (e.style.removeProperty(r.replace(/[A-Z]/g, (i) => `-${i.toLowerCase()}`)), this.recordAttributeRemoval());
|
|
1456
|
+
}), Object.entries(t).forEach(([r, i]) => {
|
|
1457
|
+
if (T(i) || P(i)) {
|
|
1458
|
+
const o = w(() => {
|
|
1459
|
+
const a = i(), h = r.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
1460
|
+
if (a == null)
|
|
1461
|
+
e.style.removeProperty(h), this.recordAttributeRemoval();
|
|
1462
|
+
else {
|
|
1463
|
+
const c = String(a);
|
|
1464
|
+
e.style.getPropertyValue(h) !== c && (e.style.setProperty(h, c), this.recordAttributeWrite());
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
this.addCleanup(e, () => {
|
|
1468
|
+
o.dispose();
|
|
1469
|
+
});
|
|
1470
|
+
} else {
|
|
1471
|
+
const o = r.replace(/[A-Z]/g, (a) => `-${a.toLowerCase()}`);
|
|
1472
|
+
if (i == null)
|
|
1473
|
+
e.style.getPropertyValue(o) && (e.style.removeProperty(o), this.recordAttributeRemoval());
|
|
1474
|
+
else {
|
|
1475
|
+
const a = String(i);
|
|
1476
|
+
e.style.getPropertyValue(o) !== a && (e.style.setProperty(o, a), this.recordAttributeWrite());
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}), e.__appliedStyles = { ...t };
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Apply event listener (with delegation if possible)
|
|
1484
|
+
*/
|
|
1485
|
+
applyEventListener(e, t, s, r) {
|
|
1486
|
+
let i = t.slice(2).toLowerCase();
|
|
1487
|
+
i === "focus" ? i = "focusin" : i === "blur" && (i = "focusout");
|
|
1488
|
+
const o = r || this.elementToContainer.get(e);
|
|
1489
|
+
if (o && Y.shouldDelegate(i)) {
|
|
1490
|
+
const c = Y.register(
|
|
1491
|
+
o,
|
|
1492
|
+
e,
|
|
1493
|
+
i,
|
|
1494
|
+
s
|
|
1495
|
+
);
|
|
1496
|
+
this.addCleanup(e, c);
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
const a = (c) => {
|
|
1500
|
+
try {
|
|
1501
|
+
s(c);
|
|
1502
|
+
} catch (l) {
|
|
1503
|
+
console.error(`Event handler error for ${t}:`, l);
|
|
1504
|
+
}
|
|
1505
|
+
}, h = Y.shouldBePassive(i) ? { passive: !0 } : void 0;
|
|
1506
|
+
e.addEventListener(i, a, h), this.addCleanup(e, () => {
|
|
1507
|
+
e.removeEventListener(i, a, h);
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Add cleanup function for an element
|
|
1512
|
+
*/
|
|
1513
|
+
addCleanup(e, t) {
|
|
1514
|
+
const s = this.cleanupMap.get(e) || [];
|
|
1515
|
+
s.push(t), this.cleanupMap.set(e, s);
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Update an existing DOM node
|
|
1519
|
+
*/
|
|
1520
|
+
updateNode(e, t) {
|
|
1521
|
+
const s = this.nodeMap.get(e);
|
|
1522
|
+
!s || typeof s.setAttribute != "function" || t && this.applyProps(s, t);
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Remove a DOM node and run cleanup
|
|
1526
|
+
*/
|
|
1527
|
+
removeNode(e) {
|
|
1528
|
+
this.cleanupNode(e, !0);
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Cleanup a node (and its descendants) and optionally remove from DOM.
|
|
1532
|
+
*/
|
|
1533
|
+
cleanupNode(e, t) {
|
|
1534
|
+
const s = this.nodeMap.get(e);
|
|
1535
|
+
if (e.children && e.children.length > 0 && e.children.forEach((i) => {
|
|
1536
|
+
this.cleanupNode(i, !1);
|
|
1537
|
+
}), !s) {
|
|
1538
|
+
e.element !== void 0 && (e.element = void 0), this.renderedNodes.delete(e), this.nodeMap.delete(e);
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1541
|
+
const r = this.cleanupMap.get(s);
|
|
1542
|
+
r && (r.forEach((i) => {
|
|
1543
|
+
try {
|
|
1544
|
+
i();
|
|
1545
|
+
} catch (o) {
|
|
1546
|
+
console.error("Cleanup error:", o);
|
|
1547
|
+
}
|
|
1548
|
+
}), this.cleanupMap.delete(s)), t && s.parentNode && s.parentNode.removeChild(s), this.nodeMap.delete(e), e.element !== void 0 && (e.element = void 0), this.renderedNodes.delete(e), this.metrics.removed++;
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Create reactive text content
|
|
1552
|
+
*/
|
|
1553
|
+
createReactiveText(e) {
|
|
1554
|
+
const t = document.createTextNode("");
|
|
1555
|
+
return w(() => {
|
|
1556
|
+
t.textContent = e();
|
|
1557
|
+
}), t;
|
|
1558
|
+
}
|
|
1559
|
+
/**
|
|
1560
|
+
* Create reactive element with dynamic props
|
|
1561
|
+
*/
|
|
1562
|
+
createReactiveElement(e, t, s) {
|
|
1563
|
+
const r = document.createElement(e);
|
|
1564
|
+
return w(() => {
|
|
1565
|
+
const i = t();
|
|
1566
|
+
this.applyProps(r, i);
|
|
1567
|
+
}), s && s.forEach((i) => {
|
|
1568
|
+
const o = this.renderSingle(i);
|
|
1569
|
+
r.appendChild(o);
|
|
1570
|
+
}), r;
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* Apply modifiers to a DOM element
|
|
1574
|
+
*/
|
|
1575
|
+
applyModifiersToElement(e, t, s) {
|
|
1576
|
+
try {
|
|
1577
|
+
t.length > 0 && this.recordModifierApplications(t.length);
|
|
1578
|
+
const r = s.componentInstance || s.componentMetadata && s.componentMetadata.componentInstance || s._originalComponent || // Use original component if available
|
|
1579
|
+
s;
|
|
1580
|
+
Ve(
|
|
1581
|
+
s,
|
|
1582
|
+
t,
|
|
1583
|
+
{
|
|
1584
|
+
element: e,
|
|
1585
|
+
componentId: s.componentId || "unknown",
|
|
1586
|
+
phase: "creation",
|
|
1587
|
+
componentInstance: r
|
|
1588
|
+
// Pass the component instance
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
batch: !0
|
|
1592
|
+
// Enable batched modifier application
|
|
1593
|
+
}
|
|
1594
|
+
);
|
|
1595
|
+
} catch (r) {
|
|
1596
|
+
console.error("Failed to apply modifiers to element:", r);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Adopt an existing DOM mapping from one node to another.
|
|
1601
|
+
*/
|
|
1602
|
+
adoptNode(e, t) {
|
|
1603
|
+
const s = this.nodeMap.get(e);
|
|
1604
|
+
s && (this.nodeMap.set(t, s), this.nodeMap.delete(e), this.renderedNodes.delete(e), this.renderedNodes.add(t), t.element = s, e.dispose && (t.dispose = e.dispose), e.__renderedChildren && (t.__renderedChildren = e.__renderedChildren), e.__appliedProps && (t.__appliedProps = e.__appliedProps), this.metrics.adopted++);
|
|
1605
|
+
}
|
|
1606
|
+
/**
|
|
1607
|
+
* Cleanup all tracked elements
|
|
1608
|
+
*/
|
|
1609
|
+
cleanup() {
|
|
1610
|
+
for (const e of this.renderedNodes)
|
|
1611
|
+
if (e.dispose && typeof e.dispose == "function")
|
|
1612
|
+
try {
|
|
1613
|
+
e.dispose();
|
|
1614
|
+
} catch (t) {
|
|
1615
|
+
console.error("Cleanup error:", t);
|
|
1616
|
+
}
|
|
1617
|
+
this.renderedNodes.clear(), this.nodeMap = /* @__PURE__ */ new WeakMap(), this.cleanupMap = /* @__PURE__ */ new WeakMap(), this.resetMetrics();
|
|
1618
|
+
}
|
|
1619
|
+
resetMetrics() {
|
|
1620
|
+
this.metrics = {
|
|
1621
|
+
created: 0,
|
|
1622
|
+
adopted: 0,
|
|
1623
|
+
removed: 0,
|
|
1624
|
+
inserted: 0,
|
|
1625
|
+
moved: 0,
|
|
1626
|
+
cacheHits: 0,
|
|
1627
|
+
cacheMisses: 0,
|
|
1628
|
+
attributeWrites: 0,
|
|
1629
|
+
attributeRemovals: 0,
|
|
1630
|
+
textUpdates: 0,
|
|
1631
|
+
modifierApplications: 0
|
|
1632
|
+
};
|
|
1633
|
+
}
|
|
1634
|
+
getMetrics() {
|
|
1635
|
+
return { ...this.metrics };
|
|
1636
|
+
}
|
|
1637
|
+
recordCacheHit() {
|
|
1638
|
+
this.metrics.cacheHits++;
|
|
1639
|
+
}
|
|
1640
|
+
recordCacheMiss() {
|
|
1641
|
+
this.metrics.cacheMisses++;
|
|
1642
|
+
}
|
|
1643
|
+
insertNode(e, t, s) {
|
|
1644
|
+
const r = typeof process < "u" && process.env?.TACHUI_DEBUG_PHASE1B === "1";
|
|
1645
|
+
t.parentNode !== e ? (r && console.log("[diff] insertNode append", {
|
|
1646
|
+
tag: "tagName" in t ? t.tagName : "text",
|
|
1647
|
+
before: s && "getAttribute" in s ? s.getAttribute("data-id") : null
|
|
1648
|
+
}), e.insertBefore(t, s), this.metrics.inserted++) : t.nextSibling !== s && (r && console.log("[diff] insertNode move", {
|
|
1649
|
+
tag: "tagName" in t ? t.tagName : "text",
|
|
1650
|
+
before: s && "getAttribute" in s ? s.getAttribute("data-id") : null
|
|
1651
|
+
}), e.insertBefore(t, s), this.metrics.moved++);
|
|
1652
|
+
}
|
|
1653
|
+
appendNode(e, t) {
|
|
1654
|
+
t.parentNode !== e && (e.appendChild(t), this.metrics.inserted++);
|
|
1655
|
+
}
|
|
1656
|
+
recordAttributeWrite() {
|
|
1657
|
+
this.metrics.attributeWrites++;
|
|
1658
|
+
}
|
|
1659
|
+
recordAttributeRemoval() {
|
|
1660
|
+
this.metrics.attributeRemovals++;
|
|
1661
|
+
}
|
|
1662
|
+
recordTextUpdate() {
|
|
1663
|
+
this.metrics.textUpdates++;
|
|
1664
|
+
}
|
|
1665
|
+
recordModifierApplications(e) {
|
|
1666
|
+
this.metrics.modifierApplications += e;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
new le();
|
|
1670
|
+
var rt = Object.defineProperty, it = (n, e, t) => e in n ? rt(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, E = (n, e, t) => it(n, typeof e != "symbol" ? e + "" : e, t);
|
|
1671
|
+
class nt {
|
|
1672
|
+
constructor(e, t) {
|
|
1673
|
+
E(this, "id"), E(this, "parent"), E(this, "providers", /* @__PURE__ */ new Map()), E(this, "consumers", /* @__PURE__ */ new Set()), E(this, "cleanup", /* @__PURE__ */ new Set()), E(this, "stateStore", /* @__PURE__ */ new Map()), E(this, "bindingStore", /* @__PURE__ */ new Map()), E(this, "createdAt", Date.now()), E(this, "updateCount", 0), this.id = e, this.parent = t;
|
|
1674
|
+
}
|
|
1675
|
+
/**
|
|
1676
|
+
* Store state value for a property
|
|
1677
|
+
*/
|
|
1678
|
+
setState(e, t) {
|
|
1679
|
+
this.stateStore.set(e, t), this.updateCount++;
|
|
1680
|
+
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Get state value for a property
|
|
1683
|
+
*/
|
|
1684
|
+
getState(e) {
|
|
1685
|
+
return this.stateStore.get(e);
|
|
1686
|
+
}
|
|
1687
|
+
/**
|
|
1688
|
+
* Check if state exists for a property
|
|
1689
|
+
*/
|
|
1690
|
+
hasState(e) {
|
|
1691
|
+
return this.stateStore.has(e);
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Store binding for a property
|
|
1695
|
+
*/
|
|
1696
|
+
setBinding(e, t) {
|
|
1697
|
+
this.bindingStore.set(e, t);
|
|
1698
|
+
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Get binding for a property
|
|
1701
|
+
*/
|
|
1702
|
+
getBinding(e) {
|
|
1703
|
+
return this.bindingStore.get(e);
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Provide a value for dependency injection
|
|
1707
|
+
*/
|
|
1708
|
+
provide(e, t) {
|
|
1709
|
+
this.providers.set(e, t);
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Consume a value from dependency injection hierarchy
|
|
1713
|
+
*/
|
|
1714
|
+
consume(e) {
|
|
1715
|
+
if (this.consumers.add(e), this.providers.has(e))
|
|
1716
|
+
return this.providers.get(e);
|
|
1717
|
+
let t = this.parent;
|
|
1718
|
+
for (; t; ) {
|
|
1719
|
+
if (t.providers.has(e))
|
|
1720
|
+
return t.providers.get(e);
|
|
1721
|
+
t = t.parent;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
/**
|
|
1725
|
+
* Register cleanup function
|
|
1726
|
+
*/
|
|
1727
|
+
onCleanup(e) {
|
|
1728
|
+
this.cleanup.add(e);
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Dispose of context and run cleanup
|
|
1732
|
+
*/
|
|
1733
|
+
dispose() {
|
|
1734
|
+
for (const e of this.cleanup)
|
|
1735
|
+
try {
|
|
1736
|
+
e();
|
|
1737
|
+
} catch (t) {
|
|
1738
|
+
console.error(`Error in component context cleanup (${this.id}):`, t);
|
|
1739
|
+
}
|
|
1740
|
+
this.cleanup.clear(), this.stateStore.clear(), this.bindingStore.clear(), this.providers.clear(), this.consumers.clear();
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Get performance metrics
|
|
1744
|
+
*/
|
|
1745
|
+
getMetrics() {
|
|
1746
|
+
return {
|
|
1747
|
+
id: this.id,
|
|
1748
|
+
createdAt: this.createdAt,
|
|
1749
|
+
updateCount: this.updateCount,
|
|
1750
|
+
stateCount: this.stateStore.size,
|
|
1751
|
+
bindingCount: this.bindingStore.size,
|
|
1752
|
+
providerCount: this.providers.size,
|
|
1753
|
+
consumerCount: this.consumers.size
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
function ot(n, e) {
|
|
1758
|
+
return new nt(n, e);
|
|
1759
|
+
}
|
|
1760
|
+
var at = Object.defineProperty, lt = (n, e, t) => e in n ? at(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, O = (n, e, t) => lt(n, typeof e != "symbol" ? e + "" : e, t);
|
|
1761
|
+
const ct = class k {
|
|
1762
|
+
constructor() {
|
|
1763
|
+
O(this, "components", /* @__PURE__ */ new Map()), O(this, "contexts", /* @__PURE__ */ new Map()), O(this, "cleanupQueue", /* @__PURE__ */ new Set()), O(this, "updateQueue", /* @__PURE__ */ new Set()), O(this, "isUpdating", !1);
|
|
1764
|
+
}
|
|
1765
|
+
static getInstance() {
|
|
1766
|
+
return k.instance || (k.instance = new k()), k.instance;
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Register a new component instance
|
|
1770
|
+
*/
|
|
1771
|
+
registerComponent(e) {
|
|
1772
|
+
this.components.set(e.id, e), e.cleanup && e.cleanup.forEach((t) => {
|
|
1773
|
+
this.cleanupQueue.add(t);
|
|
1774
|
+
});
|
|
1775
|
+
}
|
|
1776
|
+
/**
|
|
1777
|
+
* Unregister and cleanup a component
|
|
1778
|
+
*/
|
|
1779
|
+
unregisterComponent(e) {
|
|
1780
|
+
const t = this.components.get(e);
|
|
1781
|
+
t && (t.cleanup && t.cleanup.forEach((s) => {
|
|
1782
|
+
try {
|
|
1783
|
+
s();
|
|
1784
|
+
} catch (r) {
|
|
1785
|
+
console.error(`Cleanup error for component ${e}:`, r);
|
|
1786
|
+
}
|
|
1787
|
+
}), this.components.delete(e), t.context && this.cleanupContext(t.context.id));
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Get component instance by ID
|
|
1791
|
+
*/
|
|
1792
|
+
getComponent(e) {
|
|
1793
|
+
return this.components.get(e);
|
|
1794
|
+
}
|
|
1795
|
+
/**
|
|
1796
|
+
* Schedule component for update
|
|
1797
|
+
*/
|
|
1798
|
+
scheduleUpdate(e) {
|
|
1799
|
+
this.updateQueue.add(e), this.isUpdating || this.flushUpdates();
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Process all scheduled updates
|
|
1803
|
+
*/
|
|
1804
|
+
async flushUpdates() {
|
|
1805
|
+
if (this.isUpdating) return;
|
|
1806
|
+
this.isUpdating = !0, await new Promise((t) => queueMicrotask(() => t(void 0)));
|
|
1807
|
+
const e = Array.from(this.updateQueue);
|
|
1808
|
+
this.updateQueue.clear(), e.forEach((t) => {
|
|
1809
|
+
const s = this.components.get(t);
|
|
1810
|
+
if (s)
|
|
1811
|
+
try {
|
|
1812
|
+
this.updateComponent(s);
|
|
1813
|
+
} catch (r) {
|
|
1814
|
+
console.error(`Update error for component ${t}:`, r);
|
|
1815
|
+
}
|
|
1816
|
+
}), this.isUpdating = !1;
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Update a specific component instance
|
|
1820
|
+
*/
|
|
1821
|
+
updateComponent(e) {
|
|
1822
|
+
e.props && (e.prevProps = { ...e.props }), e.render(), e.mounted || (e.mounted = !0);
|
|
1823
|
+
}
|
|
1824
|
+
/**
|
|
1825
|
+
* Cleanup context by ID
|
|
1826
|
+
*/
|
|
1827
|
+
cleanupContext(e) {
|
|
1828
|
+
const t = this.contexts.get(e);
|
|
1829
|
+
t && (t.cleanup.forEach((s) => {
|
|
1830
|
+
try {
|
|
1831
|
+
s();
|
|
1832
|
+
} catch (r) {
|
|
1833
|
+
console.error(`Context cleanup error for ${e}:`, r);
|
|
1834
|
+
}
|
|
1835
|
+
}), this.contexts.delete(e));
|
|
1836
|
+
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Get all registered components (for debugging)
|
|
1839
|
+
*/
|
|
1840
|
+
getAllComponents() {
|
|
1841
|
+
return Array.from(this.components.values());
|
|
1842
|
+
}
|
|
1843
|
+
/**
|
|
1844
|
+
* Cleanup all components and resources
|
|
1845
|
+
*/
|
|
1846
|
+
cleanup() {
|
|
1847
|
+
Array.from(this.components.keys()).forEach((e) => {
|
|
1848
|
+
this.unregisterComponent(e);
|
|
1849
|
+
}), this.cleanupQueue.forEach((e) => {
|
|
1850
|
+
try {
|
|
1851
|
+
e();
|
|
1852
|
+
} catch (t) {
|
|
1853
|
+
console.error("Global cleanup error:", t);
|
|
1854
|
+
}
|
|
1855
|
+
}), this.cleanupQueue.clear(), this.updateQueue.clear();
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
O(ct, "instance");
|
|
1859
|
+
var ht = Object.defineProperty, dt = (n, e, t) => e in n ? ht(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, C = (n, e, t) => dt(n, typeof e != "symbol" ? e + "" : e, t);
|
|
1860
|
+
const ce = class z {
|
|
1861
|
+
constructor() {
|
|
1862
|
+
C(this, "contexts", /* @__PURE__ */ new Map()), C(this, "providerStack", /* @__PURE__ */ new Map()), C(this, "currentComponent", null);
|
|
1863
|
+
}
|
|
1864
|
+
static getInstance() {
|
|
1865
|
+
return z.instance || (z.instance = new z()), z.instance;
|
|
1866
|
+
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Set the current component context for provider resolution
|
|
1869
|
+
*/
|
|
1870
|
+
setCurrentComponent(e) {
|
|
1871
|
+
this.currentComponent = e;
|
|
1872
|
+
}
|
|
1873
|
+
/**
|
|
1874
|
+
* Get the current component context
|
|
1875
|
+
*/
|
|
1876
|
+
getCurrentComponent() {
|
|
1877
|
+
return this.currentComponent;
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Register a context provider
|
|
1881
|
+
*/
|
|
1882
|
+
registerProvider(e, t, s) {
|
|
1883
|
+
this.providerStack.has(e) || this.providerStack.set(e, []);
|
|
1884
|
+
const r = this.providerStack.get(e), [i, o] = G(t), a = {
|
|
1885
|
+
value: t,
|
|
1886
|
+
signal: [i, o],
|
|
1887
|
+
subscribers: /* @__PURE__ */ new Set(),
|
|
1888
|
+
providers: /* @__PURE__ */ new Set([s])
|
|
1889
|
+
};
|
|
1890
|
+
return r.push(a), s.providers.set(e, a), () => {
|
|
1891
|
+
const h = r.indexOf(a);
|
|
1892
|
+
h !== -1 && r.splice(h, 1), s.providers.delete(e), a.subscribers.clear(), a.providers.clear();
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
/**
|
|
1896
|
+
* Get context value with reactive subscription
|
|
1897
|
+
*/
|
|
1898
|
+
getContextValue(e, t) {
|
|
1899
|
+
const s = this.providerStack.get(e), r = s && s.length > 0 ? s[s.length - 1] : null;
|
|
1900
|
+
if (r)
|
|
1901
|
+
return this.currentComponent && (r.subscribers.add(this.currentComponent.id), this.currentComponent.consumers.add(e)), [r.signal[0], !0];
|
|
1902
|
+
const [i] = G(t);
|
|
1903
|
+
return [i, !1];
|
|
1904
|
+
}
|
|
1905
|
+
/**
|
|
1906
|
+
* Update context value and notify subscribers
|
|
1907
|
+
*/
|
|
1908
|
+
updateContextValue(e, t) {
|
|
1909
|
+
const s = this.providerStack.get(e), r = s && s.length > 0 ? s[s.length - 1] : null;
|
|
1910
|
+
return r ? (r.value = t, r.signal[1](t), !0) : !1;
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1913
|
+
* Get all registered contexts (for debugging)
|
|
1914
|
+
*/
|
|
1915
|
+
getAllContexts() {
|
|
1916
|
+
const e = /* @__PURE__ */ new Map();
|
|
1917
|
+
for (const [t, s] of this.providerStack.entries())
|
|
1918
|
+
s.length > 0 && e.set(t, s[s.length - 1]);
|
|
1919
|
+
return e;
|
|
1920
|
+
}
|
|
1921
|
+
/**
|
|
1922
|
+
* Clear all contexts (for testing)
|
|
1923
|
+
*/
|
|
1924
|
+
clear() {
|
|
1925
|
+
this.contexts.clear(), this.providerStack.clear(), this.currentComponent = null;
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
C(ce, "instance");
|
|
1929
|
+
let ut = ce, pt = class {
|
|
1930
|
+
constructor() {
|
|
1931
|
+
C(this, "registry", ut.getInstance());
|
|
1932
|
+
}
|
|
1933
|
+
/**
|
|
1934
|
+
* Create a context provider component
|
|
1935
|
+
*/
|
|
1936
|
+
createProvider(e, t, s) {
|
|
1937
|
+
return {
|
|
1938
|
+
type: "component",
|
|
1939
|
+
render: () => {
|
|
1940
|
+
const r = this.registry.registerProvider(
|
|
1941
|
+
e.symbol,
|
|
1942
|
+
t,
|
|
1943
|
+
ot(`provider_${e.symbol.toString()}`)
|
|
1944
|
+
), i = s.flatMap((o) => {
|
|
1945
|
+
let a = o;
|
|
1946
|
+
"build" in o && typeof o.build == "function" && (a = o.build());
|
|
1947
|
+
const h = a.render();
|
|
1948
|
+
return Array.isArray(h) ? h : [h];
|
|
1949
|
+
});
|
|
1950
|
+
return [
|
|
1951
|
+
{
|
|
1952
|
+
type: "element",
|
|
1953
|
+
tag: "div",
|
|
1954
|
+
props: { "data-context-provider": e.displayName || "provider" },
|
|
1955
|
+
children: i,
|
|
1956
|
+
dispose: r
|
|
1957
|
+
}
|
|
1958
|
+
];
|
|
1959
|
+
},
|
|
1960
|
+
props: { children: s },
|
|
1961
|
+
id: `provider_${Date.now()}`,
|
|
1962
|
+
children: s
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
/**
|
|
1966
|
+
* Set current component for context resolution
|
|
1967
|
+
*/
|
|
1968
|
+
setCurrentComponent(e) {
|
|
1969
|
+
this.registry.setCurrentComponent(e);
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* Update a context value
|
|
1973
|
+
*/
|
|
1974
|
+
updateContext(e, t) {
|
|
1975
|
+
return this.registry.updateContextValue(e.symbol, t);
|
|
1976
|
+
}
|
|
1977
|
+
/**
|
|
1978
|
+
* Get all active contexts (for debugging)
|
|
1979
|
+
*/
|
|
1980
|
+
getAllContexts() {
|
|
1981
|
+
return this.registry.getAllContexts();
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* Clear all contexts
|
|
1985
|
+
*/
|
|
1986
|
+
clear() {
|
|
1987
|
+
this.registry.clear();
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
class ft {
|
|
1991
|
+
constructor() {
|
|
1992
|
+
C(this, "services", /* @__PURE__ */ new Map()), C(this, "factories", /* @__PURE__ */ new Map()), C(this, "singletons", /* @__PURE__ */ new Map()), C(this, "scoped", /* @__PURE__ */ new Map()), C(this, "dependencies", /* @__PURE__ */ new Map());
|
|
1993
|
+
}
|
|
1994
|
+
/**
|
|
1995
|
+
* Register a service with the container
|
|
1996
|
+
*/
|
|
1997
|
+
register(e, t, s = {}) {
|
|
1998
|
+
this.services.set(e, t), s.dependencies && this.dependencies.set(e, s.dependencies), s.singleton && this.singletons.set(e, null), s.scoped && this.scoped.set(e, null);
|
|
1999
|
+
}
|
|
2000
|
+
/**
|
|
2001
|
+
* Resolve a service from the container
|
|
2002
|
+
*/
|
|
2003
|
+
resolve(e) {
|
|
2004
|
+
if (this.singletons.has(e)) {
|
|
2005
|
+
let t = this.singletons.get(e);
|
|
2006
|
+
return t === null && (t = this.createInstance(e), this.singletons.set(e, t)), t;
|
|
2007
|
+
}
|
|
2008
|
+
if (this.scoped.has(e)) {
|
|
2009
|
+
let t = this.scoped.get(e);
|
|
2010
|
+
return t === null && (t = this.createInstance(e), this.scoped.set(e, t)), t;
|
|
2011
|
+
}
|
|
2012
|
+
return this.createInstance(e);
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Create instance with dependency injection
|
|
2016
|
+
*/
|
|
2017
|
+
createInstance(e) {
|
|
2018
|
+
const t = (this.dependencies.get(e) || []).map((i) => this.resolve(i)), s = this.factories.get(e);
|
|
2019
|
+
if (s)
|
|
2020
|
+
return s(...t);
|
|
2021
|
+
const r = this.services.get(e);
|
|
2022
|
+
if (r) {
|
|
2023
|
+
if (typeof r == "function")
|
|
2024
|
+
try {
|
|
2025
|
+
return new r(...t);
|
|
2026
|
+
} catch {
|
|
2027
|
+
return r(...t);
|
|
2028
|
+
}
|
|
2029
|
+
return r;
|
|
2030
|
+
}
|
|
2031
|
+
throw new Error(`Service ${String(e)} not found in DI container`);
|
|
2032
|
+
}
|
|
2033
|
+
/**
|
|
2034
|
+
* Check if service is registered
|
|
2035
|
+
*/
|
|
2036
|
+
has(e) {
|
|
2037
|
+
return this.services.has(e) || this.factories.has(e);
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* Clear the container
|
|
2041
|
+
*/
|
|
2042
|
+
clear() {
|
|
2043
|
+
this.services.clear(), this.factories.clear(), this.singletons.clear(), this.scoped.clear(), this.dependencies.clear();
|
|
2044
|
+
}
|
|
2045
|
+
/**
|
|
2046
|
+
* Get all registered services (for debugging)
|
|
2047
|
+
*/
|
|
2048
|
+
getRegistered() {
|
|
2049
|
+
return [...this.services.keys(), ...this.factories.keys()];
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
new ft();
|
|
2053
|
+
new pt();
|
|
2054
|
+
new le();
|
|
2055
|
+
var mt = Object.defineProperty, gt = (n, e, t) => e in n ? mt(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, X = (n, e, t) => gt(n, typeof e != "symbol" ? e + "" : e, t);
|
|
2056
|
+
const yt = {
|
|
2057
|
+
sanitizeClassNames: !0,
|
|
2058
|
+
sanitizationRules: {
|
|
2059
|
+
allowNumbers: !0,
|
|
2060
|
+
allowUnderscores: !0,
|
|
2061
|
+
customReplacements: {}
|
|
2062
|
+
},
|
|
2063
|
+
enableCaching: !0,
|
|
2064
|
+
maxCacheSize: 1e3,
|
|
2065
|
+
warnDuplicateClasses: process.env.NODE_ENV === "development",
|
|
2066
|
+
warnInvalidClasses: process.env.NODE_ENV === "development"
|
|
2067
|
+
};
|
|
2068
|
+
class vt {
|
|
2069
|
+
constructor(e = {}) {
|
|
2070
|
+
X(this, "config"), X(this, "classCache"), X(this, "processingCache"), this.config = { ...yt, ...e };
|
|
2071
|
+
const t = (() => {
|
|
2072
|
+
try {
|
|
2073
|
+
return typeof Map < "u" && typeof Map == "function";
|
|
2074
|
+
} catch {
|
|
2075
|
+
return !1;
|
|
2076
|
+
}
|
|
2077
|
+
})();
|
|
2078
|
+
this.classCache = t ? /* @__PURE__ */ new Map() : {}, this.processingCache = t ? /* @__PURE__ */ new Map() : {};
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* Cache helper methods to work with both Map and plain object fallbacks
|
|
2082
|
+
*/
|
|
2083
|
+
cacheHas(e, t) {
|
|
2084
|
+
try {
|
|
2085
|
+
return e instanceof Map ? e.has(t) : t in e;
|
|
2086
|
+
} catch {
|
|
2087
|
+
return t in e;
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
cacheGet(e, t) {
|
|
2091
|
+
try {
|
|
2092
|
+
return e instanceof Map ? e.get(t) : e[t];
|
|
2093
|
+
} catch {
|
|
2094
|
+
return e[t];
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
cacheSet(e, t, s) {
|
|
2098
|
+
try {
|
|
2099
|
+
e instanceof Map ? e.set(t, s) : e[t] = s;
|
|
2100
|
+
} catch {
|
|
2101
|
+
e[t] = s;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
cacheDelete(e, t) {
|
|
2105
|
+
try {
|
|
2106
|
+
e instanceof Map ? e.delete(t) : delete e[t];
|
|
2107
|
+
} catch {
|
|
2108
|
+
delete e[t];
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
cacheClear(e) {
|
|
2112
|
+
try {
|
|
2113
|
+
e instanceof Map ? e.clear() : Object.keys(e).forEach((t) => delete e[t]);
|
|
2114
|
+
} catch {
|
|
2115
|
+
Object.keys(e).forEach((t) => delete e[t]);
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
cacheSize(e) {
|
|
2119
|
+
try {
|
|
2120
|
+
return e instanceof Map ? e.size : Object.keys(e).length;
|
|
2121
|
+
} catch {
|
|
2122
|
+
return Object.keys(e).length;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
cacheKeys(e) {
|
|
2126
|
+
try {
|
|
2127
|
+
return e instanceof Map ? e.keys() : Object.keys(e);
|
|
2128
|
+
} catch {
|
|
2129
|
+
return Object.keys(e);
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* Process CSS classes from various input formats
|
|
2134
|
+
*/
|
|
2135
|
+
processClasses(e) {
|
|
2136
|
+
if (!e) return [];
|
|
2137
|
+
if (T(e) || P(e)) {
|
|
2138
|
+
const i = e();
|
|
2139
|
+
return this.processClasses(i);
|
|
2140
|
+
}
|
|
2141
|
+
const t = this.getCacheKey(e);
|
|
2142
|
+
if (this.config.enableCaching && this.cacheHas(this.classCache, t))
|
|
2143
|
+
return this.cacheGet(this.classCache, t);
|
|
2144
|
+
let s = [];
|
|
2145
|
+
if (typeof e == "string")
|
|
2146
|
+
s = e.trim().split(/\s+/).filter(Boolean);
|
|
2147
|
+
else if (Array.isArray(e))
|
|
2148
|
+
s = e.flatMap((i) => {
|
|
2149
|
+
if (i == null || i === "")
|
|
2150
|
+
return [];
|
|
2151
|
+
const o = (typeof i == "string" ? i : String(i)).trim();
|
|
2152
|
+
return typeof i != "string" && o ? [o] : o.split(/\s+/);
|
|
2153
|
+
}).filter(Boolean);
|
|
2154
|
+
else {
|
|
2155
|
+
const i = String(e).trim();
|
|
2156
|
+
s = i ? [i] : [];
|
|
2157
|
+
}
|
|
2158
|
+
const r = this.processClassArray(s);
|
|
2159
|
+
return this.config.enableCaching && this.setCachedClasses(t, r), r;
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* Process an array of class names
|
|
2163
|
+
*/
|
|
2164
|
+
processClassArray(e) {
|
|
2165
|
+
let t = e;
|
|
2166
|
+
return this.config.sanitizeClassNames && (t = t.map((s) => this.sanitizeClassName(s))), t = this.deduplicateClasses(t), this.config.warnDuplicateClasses && e.length !== t.length && console.warn(
|
|
2167
|
+
"[tachUI] Duplicate CSS classes detected and removed:",
|
|
2168
|
+
e.filter((s, r) => e.indexOf(s) !== r)
|
|
2169
|
+
), t;
|
|
2170
|
+
}
|
|
2171
|
+
/**
|
|
2172
|
+
* Sanitize class name to be valid CSS identifier
|
|
2173
|
+
*/
|
|
2174
|
+
sanitizeClassName(e) {
|
|
2175
|
+
if (!e || typeof e != "string") return "";
|
|
2176
|
+
const t = this.config.sanitizationRules;
|
|
2177
|
+
let s = e.trim();
|
|
2178
|
+
s.includes(" ") && (s = s.replace(/\s+/g, "-"), this.config.warnInvalidClasses && console.warn(`[tachUI] CSS class names cannot contain spaces. Converted "${e}" to "${s}"`)), Object.entries(t.customReplacements || {}).forEach(([i, o]) => {
|
|
2179
|
+
s = s.replace(new RegExp(i, "g"), o);
|
|
2180
|
+
});
|
|
2181
|
+
let r = "a-zA-Z\\-\\.";
|
|
2182
|
+
return t.allowNumbers && (r += "0-9"), t.allowUnderscores && (r += "_"), r += ":\\[\\]/%", s = s.replace(new RegExp(`[^${r}]`, "g"), "-"), /^[0-9]/.test(s) && (s = "cls-" + s), s = s.replace(/---+/g, "--"), this.config.warnInvalidClasses && s !== e.trim() && console.warn(`[tachUI] CSS class "${e}" sanitized to "${s}"`), s;
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Deduplicate classes while preserving first occurrence order
|
|
2186
|
+
*/
|
|
2187
|
+
deduplicateClasses(e) {
|
|
2188
|
+
return [...new Set(e.filter(Boolean))];
|
|
2189
|
+
}
|
|
2190
|
+
/**
|
|
2191
|
+
* Combine tachUI classes with user-provided CSS classes
|
|
2192
|
+
* User classes come AFTER tachUI classes for proper CSS cascade
|
|
2193
|
+
*/
|
|
2194
|
+
combineClasses(e, t) {
|
|
2195
|
+
const s = this.processClasses(t), r = [...e, ...s];
|
|
2196
|
+
return this.deduplicateClasses(r);
|
|
2197
|
+
}
|
|
2198
|
+
/**
|
|
2199
|
+
* Update configuration
|
|
2200
|
+
*/
|
|
2201
|
+
updateConfig(e) {
|
|
2202
|
+
this.config = { ...this.config, ...e }, this.clearCaches();
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Get current configuration
|
|
2206
|
+
*/
|
|
2207
|
+
getConfig() {
|
|
2208
|
+
return { ...this.config };
|
|
2209
|
+
}
|
|
2210
|
+
/**
|
|
2211
|
+
* Clear all caches
|
|
2212
|
+
*/
|
|
2213
|
+
clearCaches() {
|
|
2214
|
+
this.cacheClear(this.classCache), this.cacheClear(this.processingCache);
|
|
2215
|
+
}
|
|
2216
|
+
/**
|
|
2217
|
+
* Get cache statistics for debugging
|
|
2218
|
+
*/
|
|
2219
|
+
getCacheStats() {
|
|
2220
|
+
return {
|
|
2221
|
+
size: this.cacheSize(this.classCache),
|
|
2222
|
+
maxSize: this.config.maxCacheSize,
|
|
2223
|
+
hitRate: 0
|
|
2224
|
+
// TODO: Implement hit rate tracking if needed
|
|
2225
|
+
};
|
|
2226
|
+
}
|
|
2227
|
+
/**
|
|
2228
|
+
* Generate cache key for input
|
|
2229
|
+
*/
|
|
2230
|
+
getCacheKey(e) {
|
|
2231
|
+
return Array.isArray(e) ? e.join("|") : e;
|
|
2232
|
+
}
|
|
2233
|
+
/**
|
|
2234
|
+
* Set cached classes with LRU eviction
|
|
2235
|
+
*/
|
|
2236
|
+
setCachedClasses(e, t) {
|
|
2237
|
+
if (this.cacheSize(this.classCache) >= this.config.maxCacheSize) {
|
|
2238
|
+
const s = this.cacheKeys(this.classCache), r = Array.isArray(s) ? s[0] : s.next().value;
|
|
2239
|
+
r !== void 0 && this.cacheDelete(this.classCache, r);
|
|
2240
|
+
}
|
|
2241
|
+
this.cacheSet(this.classCache, e, t);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
new vt();
|
|
2245
|
+
var bt = Object.defineProperty, St = (n, e, t) => e in n ? bt(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, m = (n, e, t) => St(n, typeof e != "symbol" ? e + "" : e, t);
|
|
2246
|
+
class Ct {
|
|
2247
|
+
constructor(e) {
|
|
2248
|
+
this.props = e, m(this, "type", "component"), m(this, "id"), m(this, "mounted", !1), m(this, "cleanup", []), m(this, "scrollElement", null), m(this, "contentOffsetSignal"), m(this, "setContentOffset"), m(this, "contentSizeSignal"), m(this, "setContentSize"), m(this, "setIsScrolling"), m(this, "pullToRefreshStateSignal"), m(this, "setPullToRefreshState"), m(this, "scrollEventThrottle"), m(this, "lastScrollTime", 0), m(this, "scrollVelocity", { x: 0, y: 0 }), m(this, "lastScrollOffset", { x: 0, y: 0 }), m(this, "pullStartY", 0), m(this, "isPulling", !1), m(this, "handleScroll", (c) => {
|
|
2249
|
+
if (!this.scrollElement) return;
|
|
2250
|
+
const l = performance.now(), d = l - this.lastScrollTime;
|
|
2251
|
+
if (d < this.scrollEventThrottle) return;
|
|
2252
|
+
const f = {
|
|
2253
|
+
x: this.scrollElement.scrollLeft,
|
|
2254
|
+
y: this.scrollElement.scrollTop
|
|
2255
|
+
};
|
|
2256
|
+
this.scrollVelocity = this.calculateVelocity(f, d), this.setContentOffset(f), this.setContentSize({
|
|
2257
|
+
width: this.scrollElement.scrollWidth,
|
|
2258
|
+
height: this.scrollElement.scrollHeight
|
|
2259
|
+
});
|
|
2260
|
+
const p = this.detectScrollEdges(), N = {
|
|
2261
|
+
offset: f,
|
|
2262
|
+
velocity: this.scrollVelocity,
|
|
2263
|
+
contentSize: {
|
|
2264
|
+
width: this.scrollElement.scrollWidth,
|
|
2265
|
+
height: this.scrollElement.scrollHeight
|
|
2266
|
+
},
|
|
2267
|
+
containerSize: {
|
|
2268
|
+
width: this.scrollElement.clientWidth,
|
|
2269
|
+
height: this.scrollElement.clientHeight
|
|
2270
|
+
},
|
|
2271
|
+
edges: p
|
|
2272
|
+
};
|
|
2273
|
+
this.props.onScroll && this.props.onScroll(N), p.top && this.props.onReachTop && this.props.onReachTop(), p.bottom && this.props.onReachBottom && this.props.onReachBottom(), p.left && this.props.onReachLeft && this.props.onReachLeft(), p.right && this.props.onReachRight && this.props.onReachRight(), this.lastScrollOffset = f, this.lastScrollTime = l;
|
|
2274
|
+
}), m(this, "handleScrollStart", () => {
|
|
2275
|
+
this.setIsScrolling(!0), this.props.onScrollBegin && this.props.onScrollBegin();
|
|
2276
|
+
}), m(this, "handleScrollEnd", () => {
|
|
2277
|
+
this.setIsScrolling(!1), this.props.onScrollEnd && this.props.onScrollEnd();
|
|
2278
|
+
}), m(this, "handleTouchStart", (c) => {
|
|
2279
|
+
this.props.refreshControl?.enabled && (this.pullStartY = c.touches[0].clientY, this.isPulling = !1);
|
|
2280
|
+
}), m(this, "handleTouchMove", (c) => {
|
|
2281
|
+
if (!this.props.refreshControl?.enabled || !this.scrollElement) return;
|
|
2282
|
+
const l = c.touches[0].clientY - this.pullStartY, d = this.props.refreshControl.threshold || 80;
|
|
2283
|
+
this.scrollElement.scrollTop <= 0 && l > 0 && (this.isPulling = !0, l > d ? this.setPullToRefreshState("ready") : this.setPullToRefreshState("pulling"));
|
|
2284
|
+
}), m(this, "handleTouchEnd", async () => {
|
|
2285
|
+
if (!(!this.props.refreshControl?.enabled || !this.isPulling)) {
|
|
2286
|
+
if (this.pullToRefreshStateSignal() === "ready") {
|
|
2287
|
+
this.setPullToRefreshState("refreshing");
|
|
2288
|
+
try {
|
|
2289
|
+
await this.props.refreshControl.onRefresh();
|
|
2290
|
+
} catch (c) {
|
|
2291
|
+
console.error("Pull to refresh error:", c);
|
|
2292
|
+
} finally {
|
|
2293
|
+
this.setPullToRefreshState("idle");
|
|
2294
|
+
}
|
|
2295
|
+
} else
|
|
2296
|
+
this.setPullToRefreshState("idle");
|
|
2297
|
+
this.isPulling = !1;
|
|
2298
|
+
}
|
|
2299
|
+
}), this.id = `scrollview-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, this.scrollEventThrottle = e.scrollEventThrottle || 16;
|
|
2300
|
+
const [t, s] = A(
|
|
2301
|
+
{ x: 0, y: 0 }
|
|
2302
|
+
);
|
|
2303
|
+
this.contentOffsetSignal = t, this.setContentOffset = s;
|
|
2304
|
+
const [r, i] = A({
|
|
2305
|
+
width: 0,
|
|
2306
|
+
height: 0
|
|
2307
|
+
});
|
|
2308
|
+
this.contentSizeSignal = r, this.setContentSize = i;
|
|
2309
|
+
const [, o] = A(!1);
|
|
2310
|
+
this.setIsScrolling = o;
|
|
2311
|
+
const [a, h] = A("idle");
|
|
2312
|
+
if (this.pullToRefreshStateSignal = a, this.setPullToRefreshState = h, e.contentOffset && v(e.contentOffset)) {
|
|
2313
|
+
this.setContentOffset(e.contentOffset());
|
|
2314
|
+
const c = I(() => {
|
|
2315
|
+
e.contentOffset && v(e.contentOffset) && this.setContentOffset(e.contentOffset());
|
|
2316
|
+
});
|
|
2317
|
+
this.cleanup.push(() => c.dispose());
|
|
2318
|
+
}
|
|
2319
|
+
if (e.contentSize && v(e.contentSize)) {
|
|
2320
|
+
this.setContentSize(e.contentSize());
|
|
2321
|
+
const c = I(() => {
|
|
2322
|
+
e.contentSize && v(e.contentSize) && this.setContentSize(e.contentSize());
|
|
2323
|
+
});
|
|
2324
|
+
this.cleanup.push(() => c.dispose());
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
/**
|
|
2328
|
+
* Calculate scroll velocity
|
|
2329
|
+
*/
|
|
2330
|
+
calculateVelocity(e, t) {
|
|
2331
|
+
const s = e.x - this.lastScrollOffset.x, r = e.y - this.lastScrollOffset.y;
|
|
2332
|
+
return {
|
|
2333
|
+
x: t > 0 ? s / t : 0,
|
|
2334
|
+
y: t > 0 ? r / t : 0
|
|
2335
|
+
};
|
|
2336
|
+
}
|
|
2337
|
+
/**
|
|
2338
|
+
* Detect scroll edges
|
|
2339
|
+
*/
|
|
2340
|
+
detectScrollEdges() {
|
|
2341
|
+
if (!this.scrollElement)
|
|
2342
|
+
return { top: !1, bottom: !1, left: !1, right: !1 };
|
|
2343
|
+
const {
|
|
2344
|
+
scrollTop: e,
|
|
2345
|
+
scrollLeft: t,
|
|
2346
|
+
scrollHeight: s,
|
|
2347
|
+
scrollWidth: r,
|
|
2348
|
+
clientHeight: i,
|
|
2349
|
+
clientWidth: o
|
|
2350
|
+
} = this.scrollElement;
|
|
2351
|
+
return {
|
|
2352
|
+
top: e <= 0,
|
|
2353
|
+
bottom: e + i >= s - 1,
|
|
2354
|
+
left: t <= 0,
|
|
2355
|
+
right: t + o >= r - 1
|
|
2356
|
+
};
|
|
2357
|
+
}
|
|
2358
|
+
/**
|
|
2359
|
+
* Set up scroll event handlers
|
|
2360
|
+
*/
|
|
2361
|
+
setupScrollHandlers(e) {
|
|
2362
|
+
let t;
|
|
2363
|
+
const s = () => {
|
|
2364
|
+
clearTimeout(t), this.handleScrollStart();
|
|
2365
|
+
}, r = () => {
|
|
2366
|
+
clearTimeout(t), t = setTimeout(() => {
|
|
2367
|
+
this.handleScrollEnd();
|
|
2368
|
+
}, 150);
|
|
2369
|
+
}, i = (o) => {
|
|
2370
|
+
s(), this.handleScroll(o), r();
|
|
2371
|
+
};
|
|
2372
|
+
e.addEventListener("scroll", i, { passive: !0 }), e.addEventListener("touchstart", this.handleTouchStart, {
|
|
2373
|
+
passive: !0
|
|
2374
|
+
}), e.addEventListener("touchmove", this.handleTouchMove, {
|
|
2375
|
+
passive: !1
|
|
2376
|
+
}), e.addEventListener("touchend", this.handleTouchEnd, { passive: !0 }), this.cleanup.push(() => {
|
|
2377
|
+
e.removeEventListener("scroll", i), e.removeEventListener("touchstart", this.handleTouchStart), e.removeEventListener("touchmove", this.handleTouchMove), e.removeEventListener("touchend", this.handleTouchEnd), clearTimeout(t);
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
/**
|
|
2381
|
+
* Get overflow styles based on direction
|
|
2382
|
+
*/
|
|
2383
|
+
getOverflowStyles(e) {
|
|
2384
|
+
switch (e) {
|
|
2385
|
+
case "vertical":
|
|
2386
|
+
return {
|
|
2387
|
+
overflowX: "hidden",
|
|
2388
|
+
overflowY: "auto"
|
|
2389
|
+
};
|
|
2390
|
+
case "horizontal":
|
|
2391
|
+
return {
|
|
2392
|
+
overflowX: "auto",
|
|
2393
|
+
overflowY: "hidden"
|
|
2394
|
+
};
|
|
2395
|
+
case "both":
|
|
2396
|
+
return {
|
|
2397
|
+
overflow: "auto"
|
|
2398
|
+
};
|
|
2399
|
+
default:
|
|
2400
|
+
return {
|
|
2401
|
+
overflowX: "hidden",
|
|
2402
|
+
overflowY: "auto"
|
|
2403
|
+
};
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Apply additional scroll view styling (position and overflow already set in initial render)
|
|
2408
|
+
*/
|
|
2409
|
+
applyScrollViewStyles(e) {
|
|
2410
|
+
const { showsScrollIndicator: t = !0, bounces: s = !0 } = this.props;
|
|
2411
|
+
if (!t) {
|
|
2412
|
+
e.style.scrollbarWidth = "none", e.style.msOverflowStyle = "none";
|
|
2413
|
+
const r = document.createElement("style");
|
|
2414
|
+
r.textContent = `
|
|
2415
|
+
#${e.id}::-webkit-scrollbar {
|
|
2416
|
+
display: none;
|
|
2417
|
+
}
|
|
2418
|
+
`, document.head.appendChild(r), this.cleanup.push(() => {
|
|
2419
|
+
document.head.removeChild(r);
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
s ? e.style.webkitOverflowScrolling = "touch" : e.style.overscrollBehavior = "none", e.style.scrollBehavior = "smooth";
|
|
2423
|
+
}
|
|
2424
|
+
/**
|
|
2425
|
+
* Apply content insets
|
|
2426
|
+
*/
|
|
2427
|
+
applyContentInsets(e) {
|
|
2428
|
+
const { contentInset: t } = this.props;
|
|
2429
|
+
if (t) {
|
|
2430
|
+
const { top: s = 0, bottom: r = 0, left: i = 0, right: o = 0 } = t;
|
|
2431
|
+
e.style.padding = `${s}px ${o}px ${r}px ${i}px`;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
/**
|
|
2435
|
+
* Create pull to refresh indicator
|
|
2436
|
+
*/
|
|
2437
|
+
createPullToRefreshIndicator() {
|
|
2438
|
+
if (!this.props.refreshControl?.enabled) return null;
|
|
2439
|
+
const e = this.pullToRefreshStateSignal(), t = this.props.refreshControl.tintColor || "#007AFF";
|
|
2440
|
+
let s = "";
|
|
2441
|
+
switch (e) {
|
|
2442
|
+
case "pulling":
|
|
2443
|
+
s = "↓ Pull to refresh";
|
|
2444
|
+
break;
|
|
2445
|
+
case "ready":
|
|
2446
|
+
s = "↑ Release to refresh";
|
|
2447
|
+
break;
|
|
2448
|
+
case "refreshing":
|
|
2449
|
+
s = "⟳ Refreshing...";
|
|
2450
|
+
break;
|
|
2451
|
+
default:
|
|
2452
|
+
s = "";
|
|
2453
|
+
}
|
|
2454
|
+
return s ? {
|
|
2455
|
+
type: "component",
|
|
2456
|
+
id: `${this.id}-refresh`,
|
|
2457
|
+
mounted: !1,
|
|
2458
|
+
cleanup: [],
|
|
2459
|
+
props: {},
|
|
2460
|
+
render: () => [
|
|
2461
|
+
b(
|
|
2462
|
+
"div",
|
|
2463
|
+
{
|
|
2464
|
+
style: {
|
|
2465
|
+
position: "absolute",
|
|
2466
|
+
top: "-60px",
|
|
2467
|
+
left: "50%",
|
|
2468
|
+
transform: "translateX(-50%)",
|
|
2469
|
+
padding: "10px 20px",
|
|
2470
|
+
backgroundColor: "#f8f9fa",
|
|
2471
|
+
borderRadius: "20px",
|
|
2472
|
+
color: t,
|
|
2473
|
+
fontSize: "14px",
|
|
2474
|
+
fontWeight: "500",
|
|
2475
|
+
textAlign: "center",
|
|
2476
|
+
zIndex: 1e3,
|
|
2477
|
+
transition: "all 0.3s ease",
|
|
2478
|
+
opacity: e === "idle" ? 0 : 1
|
|
2479
|
+
}
|
|
2480
|
+
},
|
|
2481
|
+
s
|
|
2482
|
+
)
|
|
2483
|
+
]
|
|
2484
|
+
} : null;
|
|
2485
|
+
}
|
|
2486
|
+
/**
|
|
2487
|
+
* Scroll to specific position
|
|
2488
|
+
*/
|
|
2489
|
+
scrollTo(e, t = "smooth") {
|
|
2490
|
+
if (!this.scrollElement) return;
|
|
2491
|
+
const s = { behavior: t };
|
|
2492
|
+
e.x !== void 0 && (s.left = e.x), e.y !== void 0 && (s.top = e.y), this.scrollElement.scrollTo(s);
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* Scroll to top
|
|
2496
|
+
*/
|
|
2497
|
+
scrollToTop(e = "smooth") {
|
|
2498
|
+
this.scrollTo({ x: 0, y: 0 }, e);
|
|
2499
|
+
}
|
|
2500
|
+
/**
|
|
2501
|
+
* Scroll to bottom
|
|
2502
|
+
*/
|
|
2503
|
+
scrollToBottom(e = "smooth") {
|
|
2504
|
+
this.scrollElement && this.scrollTo(
|
|
2505
|
+
{
|
|
2506
|
+
x: 0,
|
|
2507
|
+
y: this.scrollElement.scrollHeight - this.scrollElement.clientHeight
|
|
2508
|
+
},
|
|
2509
|
+
e
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* Render the scroll view component
|
|
2514
|
+
*/
|
|
2515
|
+
render() {
|
|
2516
|
+
const { children: e = [], scrollEnabled: t = !0 } = this.props;
|
|
2517
|
+
let s = [];
|
|
2518
|
+
const r = e;
|
|
2519
|
+
if (typeof r == "function") {
|
|
2520
|
+
const d = r();
|
|
2521
|
+
s = Array.isArray(d) ? d : [];
|
|
2522
|
+
} else Array.isArray(e) && (s = e);
|
|
2523
|
+
const i = b(
|
|
2524
|
+
"div",
|
|
2525
|
+
{
|
|
2526
|
+
class: "tachui-scrollview-content",
|
|
2527
|
+
style: {
|
|
2528
|
+
minHeight: "100%",
|
|
2529
|
+
minWidth: "100%"
|
|
2530
|
+
}
|
|
2531
|
+
},
|
|
2532
|
+
...s.flatMap((d) => d.render())
|
|
2533
|
+
), o = this.createPullToRefreshIndicator(), a = [];
|
|
2534
|
+
if (o) {
|
|
2535
|
+
const d = o.render(), f = Array.isArray(d) ? d : [d];
|
|
2536
|
+
a.push(...f.filter((p) => p));
|
|
2537
|
+
}
|
|
2538
|
+
a.push(i);
|
|
2539
|
+
const { direction: h = "vertical" } = this.props, c = this.getOverflowStyles(h), l = b(
|
|
2540
|
+
"div",
|
|
2541
|
+
{
|
|
2542
|
+
id: this.id,
|
|
2543
|
+
class: "tachui-scrollview",
|
|
2544
|
+
style: {
|
|
2545
|
+
height: "100%",
|
|
2546
|
+
width: "100%",
|
|
2547
|
+
position: "relative",
|
|
2548
|
+
...c
|
|
2549
|
+
}
|
|
2550
|
+
},
|
|
2551
|
+
...a
|
|
2552
|
+
);
|
|
2553
|
+
if (l.element) {
|
|
2554
|
+
const d = l.element;
|
|
2555
|
+
this.scrollElement = d, this.applyScrollViewStyles(d), this.setupScrollHandlers(d), i.element && this.applyContentInsets(i.element);
|
|
2556
|
+
const f = () => {
|
|
2557
|
+
const p = v(t) ? t() : t;
|
|
2558
|
+
d.style.overflow = p ? "auto" : "hidden", d.style.pointerEvents = p ? "auto" : "none";
|
|
2559
|
+
};
|
|
2560
|
+
if (v(t)) {
|
|
2561
|
+
const p = I(f);
|
|
2562
|
+
this.cleanup.push(() => p.dispose());
|
|
2563
|
+
} else
|
|
2564
|
+
f();
|
|
2565
|
+
if (typeof r == "function") {
|
|
2566
|
+
const p = I(() => {
|
|
2567
|
+
const N = r(), he = (Array.isArray(N) ? N : []).flatMap((V) => V.render());
|
|
2568
|
+
if (i.element) {
|
|
2569
|
+
const V = i.element;
|
|
2570
|
+
V.innerHTML = "", he.forEach((W) => {
|
|
2571
|
+
W && W.element && V.appendChild(W.element);
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
});
|
|
2575
|
+
this.cleanup.push(() => p.dispose());
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
return [l];
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
function Et(n = {}) {
|
|
2582
|
+
const e = new Ct(n);
|
|
2583
|
+
return re(e);
|
|
2584
|
+
}
|
|
2585
|
+
const wt = `
|
|
2586
|
+
@keyframes spin {
|
|
2587
|
+
from { transform: rotate(0deg); }
|
|
2588
|
+
to { transform: rotate(360deg); }
|
|
2589
|
+
}
|
|
2590
|
+
`;
|
|
2591
|
+
if (typeof document < "u") {
|
|
2592
|
+
const n = document.createElement("style");
|
|
2593
|
+
n.textContent = wt, document.head.appendChild(n);
|
|
2594
|
+
}
|
|
2595
|
+
process.env.NODE_ENV;
|
|
2596
|
+
class At {
|
|
2597
|
+
constructor(e) {
|
|
2598
|
+
u(this, "type", "component");
|
|
2599
|
+
u(this, "id");
|
|
2600
|
+
u(this, "mounted", !1);
|
|
2601
|
+
u(this, "cleanup", []);
|
|
2602
|
+
u(this, "dataSignal");
|
|
2603
|
+
u(this, "setData");
|
|
2604
|
+
u(this, "sectionsSignal");
|
|
2605
|
+
u(this, "setSections");
|
|
2606
|
+
u(this, "selectedItemsSignal");
|
|
2607
|
+
u(this, "setSelectedItems");
|
|
2608
|
+
u(this, "isLoadingSignal");
|
|
2609
|
+
u(this, "setIsLoading");
|
|
20
2610
|
// Virtual scrolling state
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
2611
|
+
u(this, "virtualItems", []);
|
|
2612
|
+
u(this, "visibleStartIndex", 0);
|
|
2613
|
+
u(this, "visibleEndIndex", 0);
|
|
2614
|
+
u(this, "scrollOffset", 0);
|
|
2615
|
+
u(this, "containerHeight", 0);
|
|
2616
|
+
u(this, "totalHeight", 0);
|
|
27
2617
|
/**
|
|
28
2618
|
* Handle scroll events for virtual scrolling and infinite scroll
|
|
29
2619
|
*/
|
|
30
|
-
|
|
31
|
-
this.scrollOffset =
|
|
2620
|
+
u(this, "handleListScroll", (e) => {
|
|
2621
|
+
this.scrollOffset = e.offset.y, this.containerHeight = e.containerSize.height, this.props.virtualScrolling?.enabled && this.calculateVisibleRange(), this.props.onLoadMore && e.edges.bottom && (v(this.props.hasMore) ? this.props.hasMore() : this.props.hasMore) && !this.isLoadingSignal() && (this.setIsLoading(!0), this.props.onLoadMore().finally(() => {
|
|
32
2622
|
this.setIsLoading(!1);
|
|
33
|
-
})), this.props.onScroll && this.props.onScroll(
|
|
2623
|
+
})), this.props.onScroll && this.props.onScroll(e);
|
|
34
2624
|
});
|
|
35
|
-
this.props =
|
|
36
|
-
const [
|
|
37
|
-
this.dataSignal =
|
|
38
|
-
const [r, i] =
|
|
2625
|
+
this.props = e, this.id = `list-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2626
|
+
const [t, s] = A(this.resolveData());
|
|
2627
|
+
this.dataSignal = t, this.setData = s;
|
|
2628
|
+
const [r, i] = A(
|
|
39
2629
|
this.resolveSections()
|
|
40
2630
|
);
|
|
41
2631
|
this.sectionsSignal = r, this.setSections = i;
|
|
42
|
-
const
|
|
43
|
-
this.selectedItemsSignal =
|
|
44
|
-
const [
|
|
2632
|
+
const o = /* @__PURE__ */ new Set(), [a, h] = A(o);
|
|
2633
|
+
this.selectedItemsSignal = a, this.setSelectedItems = h;
|
|
2634
|
+
const [c, l] = A(
|
|
45
2635
|
this.resolveIsLoading()
|
|
46
2636
|
);
|
|
47
|
-
this.isLoadingSignal =
|
|
2637
|
+
this.isLoadingSignal = c, this.setIsLoading = l, this.setupReactiveUpdates(), e.virtualScrolling?.enabled && this.initializeVirtualScrolling();
|
|
48
2638
|
}
|
|
49
2639
|
/**
|
|
50
2640
|
* Helper to flatten render results
|
|
51
2641
|
*/
|
|
52
|
-
flattenRenderResult(
|
|
53
|
-
return Array.isArray(
|
|
2642
|
+
flattenRenderResult(e) {
|
|
2643
|
+
return Array.isArray(e) ? e : [e];
|
|
2644
|
+
}
|
|
2645
|
+
/**
|
|
2646
|
+
* Normalize item render output into safe DOM node payloads.
|
|
2647
|
+
*
|
|
2648
|
+
* Strings and primitives are always emitted as text nodes to avoid HTML
|
|
2649
|
+
* interpretation in list item rendering.
|
|
2650
|
+
*/
|
|
2651
|
+
normalizeItemRenderOutput(e) {
|
|
2652
|
+
return e && typeof e.render == "function" ? this.flattenRenderResult(e.render()) : e == null || e === !1 ? [] : typeof e == "string" || typeof e == "number" || typeof e == "boolean" ? [{ type: "text", text: String(e) }] : this.flattenRenderResult(e);
|
|
54
2653
|
}
|
|
55
2654
|
/**
|
|
56
2655
|
* Resolve data from various input types
|
|
57
2656
|
*/
|
|
58
2657
|
resolveData() {
|
|
59
|
-
const { data:
|
|
60
|
-
return Array.isArray(
|
|
2658
|
+
const { data: e } = this.props;
|
|
2659
|
+
return Array.isArray(e) ? e : v(e) ? e() : [];
|
|
61
2660
|
}
|
|
62
2661
|
/**
|
|
63
2662
|
* Resolve sections from various input types
|
|
64
2663
|
*/
|
|
65
2664
|
resolveSections() {
|
|
66
|
-
const { sections:
|
|
67
|
-
return Array.isArray(
|
|
2665
|
+
const { sections: e } = this.props;
|
|
2666
|
+
return Array.isArray(e) ? e : v(e) ? e() : [];
|
|
68
2667
|
}
|
|
69
2668
|
/**
|
|
70
2669
|
* Resolve loading state
|
|
71
2670
|
*/
|
|
72
2671
|
resolveIsLoading() {
|
|
73
|
-
const { isLoading:
|
|
74
|
-
return typeof
|
|
2672
|
+
const { isLoading: e } = this.props;
|
|
2673
|
+
return typeof e == "boolean" ? e : v(e) ? e() : !1;
|
|
75
2674
|
}
|
|
76
2675
|
/**
|
|
77
2676
|
* Set up reactive updates for data and state
|
|
78
2677
|
*/
|
|
79
2678
|
setupReactiveUpdates() {
|
|
80
|
-
if (
|
|
81
|
-
const
|
|
2679
|
+
if (v(this.props.data)) {
|
|
2680
|
+
const e = I(() => {
|
|
82
2681
|
this.setData(this.resolveData()), this.updateVirtualScrolling();
|
|
83
2682
|
});
|
|
84
|
-
this.cleanup.push(() =>
|
|
2683
|
+
this.cleanup.push(() => e.dispose());
|
|
85
2684
|
}
|
|
86
|
-
if (
|
|
87
|
-
const
|
|
2685
|
+
if (v(this.props.sections)) {
|
|
2686
|
+
const e = I(() => {
|
|
88
2687
|
this.setSections(this.resolveSections()), this.updateVirtualScrolling();
|
|
89
2688
|
});
|
|
90
|
-
this.cleanup.push(() =>
|
|
2689
|
+
this.cleanup.push(() => e.dispose());
|
|
91
2690
|
}
|
|
92
|
-
if (
|
|
93
|
-
const
|
|
2691
|
+
if (v(this.props.isLoading)) {
|
|
2692
|
+
const e = I(() => {
|
|
94
2693
|
this.setIsLoading(this.resolveIsLoading());
|
|
95
2694
|
});
|
|
96
|
-
this.cleanup.push(() =>
|
|
2695
|
+
this.cleanup.push(() => e.dispose());
|
|
97
2696
|
}
|
|
98
2697
|
if (this.props.selectedItems) {
|
|
99
|
-
const
|
|
2698
|
+
const e = I(() => {
|
|
100
2699
|
this.props.selectedItems && this.setSelectedItems(this.props.selectedItems());
|
|
101
2700
|
});
|
|
102
|
-
this.cleanup.push(() =>
|
|
2701
|
+
this.cleanup.push(() => e.dispose());
|
|
103
2702
|
}
|
|
104
2703
|
}
|
|
105
2704
|
/**
|
|
106
2705
|
* Initialize virtual scrolling calculations
|
|
107
2706
|
*/
|
|
108
2707
|
initializeVirtualScrolling() {
|
|
109
|
-
const
|
|
110
|
-
this.virtualItems =
|
|
2708
|
+
const e = this.dataSignal(), s = this.props.virtualScrolling.estimatedItemHeight || 50;
|
|
2709
|
+
this.virtualItems = e.map((r, i) => ({
|
|
111
2710
|
index: i,
|
|
112
|
-
height:
|
|
113
|
-
offset: i *
|
|
2711
|
+
height: s,
|
|
2712
|
+
offset: i * s,
|
|
114
2713
|
item: r
|
|
115
|
-
})), this.totalHeight =
|
|
2714
|
+
})), this.totalHeight = e.length * s;
|
|
116
2715
|
}
|
|
117
2716
|
/**
|
|
118
2717
|
* Update virtual scrolling calculations
|
|
@@ -125,17 +2724,17 @@ class $ {
|
|
|
125
2724
|
*/
|
|
126
2725
|
calculateVisibleRange() {
|
|
127
2726
|
if (!this.props.virtualScrolling?.enabled) return;
|
|
128
|
-
const
|
|
2727
|
+
const e = this.props.virtualScrolling, t = e.overscan || 5, s = e.threshold || 0;
|
|
129
2728
|
let r = 0;
|
|
130
|
-
for (let
|
|
131
|
-
if (this.virtualItems[
|
|
132
|
-
r = Math.max(0,
|
|
2729
|
+
for (let o = 0; o < this.virtualItems.length; o++)
|
|
2730
|
+
if (this.virtualItems[o].offset + this.virtualItems[o].height > this.scrollOffset - s) {
|
|
2731
|
+
r = Math.max(0, o - t);
|
|
133
2732
|
break;
|
|
134
2733
|
}
|
|
135
2734
|
let i = this.virtualItems.length - 1;
|
|
136
|
-
for (let
|
|
137
|
-
if (this.virtualItems[
|
|
138
|
-
i = Math.min(this.virtualItems.length - 1,
|
|
2735
|
+
for (let o = r; o < this.virtualItems.length; o++)
|
|
2736
|
+
if (this.virtualItems[o].offset > this.scrollOffset + this.containerHeight + s) {
|
|
2737
|
+
i = Math.min(this.virtualItems.length - 1, o + t);
|
|
139
2738
|
break;
|
|
140
2739
|
}
|
|
141
2740
|
this.visibleStartIndex = r, this.visibleEndIndex = i;
|
|
@@ -143,25 +2742,25 @@ class $ {
|
|
|
143
2742
|
/**
|
|
144
2743
|
* Handle item selection
|
|
145
2744
|
*/
|
|
146
|
-
handleItemSelection(
|
|
147
|
-
const { selectionMode:
|
|
148
|
-
if (
|
|
149
|
-
const
|
|
150
|
-
|
|
2745
|
+
handleItemSelection(e, t) {
|
|
2746
|
+
const { selectionMode: s, getItemId: r, onSelectionChange: i } = this.props;
|
|
2747
|
+
if (s === "none") return;
|
|
2748
|
+
const o = r ? r(e, t) : t, a = new Set(this.selectedItemsSignal());
|
|
2749
|
+
s === "single" ? (a.clear(), a.add(o)) : s === "multiple" && (a.has(o) ? a.delete(o) : a.add(o)), this.setSelectedItems(a), i && i(a);
|
|
151
2750
|
}
|
|
152
2751
|
/**
|
|
153
2752
|
* Create list item component
|
|
154
2753
|
*/
|
|
155
|
-
createListItem(
|
|
156
|
-
const { renderItem: r, style: i, onItemTap:
|
|
2754
|
+
createListItem(e, t, s) {
|
|
2755
|
+
const { renderItem: r, style: i, onItemTap: o, onItemLongPress: a } = this.props, h = r(e, t);
|
|
157
2756
|
return {
|
|
158
2757
|
type: "component",
|
|
159
|
-
id: `${this.id}-item-${
|
|
2758
|
+
id: `${this.id}-item-${t}`,
|
|
160
2759
|
mounted: !1,
|
|
161
2760
|
cleanup: [],
|
|
162
2761
|
props: {},
|
|
163
2762
|
render: () => {
|
|
164
|
-
const
|
|
2763
|
+
const c = b(
|
|
165
2764
|
"div",
|
|
166
2765
|
{
|
|
167
2766
|
class: `tachui-list-item tachui-list-item-${i || "plain"}`,
|
|
@@ -169,32 +2768,32 @@ class $ {
|
|
|
169
2768
|
display: "flex",
|
|
170
2769
|
flexDirection: "column",
|
|
171
2770
|
position: "relative",
|
|
172
|
-
backgroundColor:
|
|
2771
|
+
backgroundColor: s ? "#e6f3ff" : "transparent",
|
|
173
2772
|
transition: "background-color 0.2s ease",
|
|
174
|
-
cursor:
|
|
2773
|
+
cursor: o ? "pointer" : "default"
|
|
175
2774
|
}
|
|
176
2775
|
},
|
|
177
|
-
...this.
|
|
2776
|
+
...this.normalizeItemRenderOutput(h)
|
|
178
2777
|
);
|
|
179
|
-
if (
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
182
|
-
let
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
() =>
|
|
2778
|
+
if (c.element) {
|
|
2779
|
+
const l = c.element;
|
|
2780
|
+
if (o && l.addEventListener("click", () => o(e, t)), a) {
|
|
2781
|
+
let d;
|
|
2782
|
+
const f = () => {
|
|
2783
|
+
d = setTimeout(
|
|
2784
|
+
() => a(e, t),
|
|
186
2785
|
500
|
|
187
2786
|
);
|
|
188
|
-
},
|
|
189
|
-
clearTimeout(
|
|
2787
|
+
}, p = () => {
|
|
2788
|
+
clearTimeout(d);
|
|
190
2789
|
};
|
|
191
|
-
|
|
2790
|
+
l.addEventListener("mousedown", f), l.addEventListener("mouseup", p), l.addEventListener("mouseleave", p), l.addEventListener("touchstart", f), l.addEventListener("touchend", p);
|
|
192
2791
|
}
|
|
193
|
-
this.props.selectionMode !== "none" &&
|
|
194
|
-
(
|
|
2792
|
+
this.props.selectionMode !== "none" && l.addEventListener("click", (d) => {
|
|
2793
|
+
(d.metaKey || d.ctrlKey || this.props.selectionMode === "multiple") && (d.preventDefault(), this.handleItemSelection(e, t));
|
|
195
2794
|
});
|
|
196
2795
|
}
|
|
197
|
-
return [
|
|
2796
|
+
return [c];
|
|
198
2797
|
}
|
|
199
2798
|
};
|
|
200
2799
|
}
|
|
@@ -202,15 +2801,15 @@ class $ {
|
|
|
202
2801
|
* Create list separator
|
|
203
2802
|
*/
|
|
204
2803
|
createSeparator() {
|
|
205
|
-
const { separator:
|
|
206
|
-
return
|
|
2804
|
+
const { separator: e } = this.props;
|
|
2805
|
+
return e ? typeof e == "object" && "render" in e ? e : {
|
|
207
2806
|
type: "component",
|
|
208
2807
|
id: `${this.id}-separator`,
|
|
209
2808
|
mounted: !1,
|
|
210
2809
|
cleanup: [],
|
|
211
2810
|
props: {},
|
|
212
2811
|
render: () => [
|
|
213
|
-
|
|
2812
|
+
b("div", {
|
|
214
2813
|
class: "tachui-list-separator",
|
|
215
2814
|
style: {
|
|
216
2815
|
height: "1px",
|
|
@@ -224,72 +2823,66 @@ class $ {
|
|
|
224
2823
|
/**
|
|
225
2824
|
* Create section header
|
|
226
2825
|
*/
|
|
227
|
-
createSectionHeader(
|
|
228
|
-
return
|
|
2826
|
+
createSectionHeader(e, t) {
|
|
2827
|
+
return e.header ? typeof e.header == "string" ? {
|
|
229
2828
|
type: "component",
|
|
230
|
-
id: `${this.id}-section-header-${
|
|
2829
|
+
id: `${this.id}-section-header-${t}`,
|
|
231
2830
|
mounted: !1,
|
|
232
2831
|
cleanup: [],
|
|
233
2832
|
props: {},
|
|
234
|
-
render: () =>
|
|
235
|
-
|
|
236
|
-
"
|
|
237
|
-
{
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
)
|
|
251
|
-
]
|
|
252
|
-
} : this.props.renderSectionHeader ? this.props.renderSectionHeader(t, e) : t.header : null;
|
|
2833
|
+
render: () => {
|
|
2834
|
+
const s = b("div", {
|
|
2835
|
+
class: "tachui-list-section-header",
|
|
2836
|
+
style: {
|
|
2837
|
+
padding: "8px 16px",
|
|
2838
|
+
backgroundColor: "#f8f9fa",
|
|
2839
|
+
fontWeight: "600",
|
|
2840
|
+
fontSize: "14px",
|
|
2841
|
+
color: "#666",
|
|
2842
|
+
textTransform: "uppercase",
|
|
2843
|
+
letterSpacing: "0.5px"
|
|
2844
|
+
}
|
|
2845
|
+
}), r = s.element;
|
|
2846
|
+
return r && (r.textContent = e.header), [s];
|
|
2847
|
+
}
|
|
2848
|
+
} : this.props.renderSectionHeader ? this.props.renderSectionHeader(e, t) : e.header : null;
|
|
253
2849
|
}
|
|
254
2850
|
/**
|
|
255
2851
|
* Create section footer
|
|
256
2852
|
*/
|
|
257
|
-
createSectionFooter(
|
|
258
|
-
return
|
|
2853
|
+
createSectionFooter(e, t) {
|
|
2854
|
+
return e.footer ? typeof e.footer == "string" ? {
|
|
259
2855
|
type: "component",
|
|
260
|
-
id: `${this.id}-section-footer-${
|
|
2856
|
+
id: `${this.id}-section-footer-${t}`,
|
|
261
2857
|
mounted: !1,
|
|
262
2858
|
cleanup: [],
|
|
263
2859
|
props: {},
|
|
264
|
-
render: () =>
|
|
265
|
-
|
|
266
|
-
"
|
|
267
|
-
{
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
)
|
|
277
|
-
]
|
|
278
|
-
} : this.props.renderSectionFooter ? this.props.renderSectionFooter(t, e) : t.footer : null;
|
|
2860
|
+
render: () => {
|
|
2861
|
+
const s = b("div", {
|
|
2862
|
+
class: "tachui-list-section-footer",
|
|
2863
|
+
style: {
|
|
2864
|
+
padding: "8px 16px",
|
|
2865
|
+
fontSize: "12px",
|
|
2866
|
+
color: "#999"
|
|
2867
|
+
}
|
|
2868
|
+
}), r = s.element;
|
|
2869
|
+
return r && (r.textContent = e.footer), [s];
|
|
2870
|
+
}
|
|
2871
|
+
} : this.props.renderSectionFooter ? this.props.renderSectionFooter(e, t) : e.footer : null;
|
|
279
2872
|
}
|
|
280
2873
|
/**
|
|
281
2874
|
* Create empty state component
|
|
282
2875
|
*/
|
|
283
2876
|
createEmptyState() {
|
|
284
|
-
const { emptyState:
|
|
285
|
-
return
|
|
2877
|
+
const { emptyState: e } = this.props;
|
|
2878
|
+
return e || {
|
|
286
2879
|
type: "component",
|
|
287
2880
|
id: `${this.id}-empty`,
|
|
288
2881
|
mounted: !1,
|
|
289
2882
|
cleanup: [],
|
|
290
2883
|
props: {},
|
|
291
2884
|
render: () => [
|
|
292
|
-
|
|
2885
|
+
b(
|
|
293
2886
|
"div",
|
|
294
2887
|
{
|
|
295
2888
|
class: "tachui-list-empty",
|
|
@@ -312,15 +2905,15 @@ class $ {
|
|
|
312
2905
|
* Create loading indicator
|
|
313
2906
|
*/
|
|
314
2907
|
createLoadingIndicator() {
|
|
315
|
-
const { loadingIndicator:
|
|
316
|
-
return
|
|
2908
|
+
const { loadingIndicator: e } = this.props;
|
|
2909
|
+
return e || {
|
|
317
2910
|
type: "component",
|
|
318
2911
|
id: `${this.id}-loading`,
|
|
319
2912
|
mounted: !1,
|
|
320
2913
|
cleanup: [],
|
|
321
2914
|
props: {},
|
|
322
2915
|
render: () => [
|
|
323
|
-
|
|
2916
|
+
b(
|
|
324
2917
|
"div",
|
|
325
2918
|
{
|
|
326
2919
|
class: "tachui-list-loading",
|
|
@@ -343,7 +2936,7 @@ class $ {
|
|
|
343
2936
|
renderVirtualContent() {
|
|
344
2937
|
if (!this.props.virtualScrolling?.enabled)
|
|
345
2938
|
return this.renderRegularContent();
|
|
346
|
-
const
|
|
2939
|
+
const e = this.dataSignal(), t = this.selectedItemsSignal(), s = this.createSeparator(), r = [];
|
|
347
2940
|
if (this.visibleStartIndex > 0) {
|
|
348
2941
|
const i = this.virtualItems[this.visibleStartIndex]?.offset || 0;
|
|
349
2942
|
r.push({
|
|
@@ -353,17 +2946,17 @@ class $ {
|
|
|
353
2946
|
cleanup: [],
|
|
354
2947
|
props: {},
|
|
355
2948
|
render: () => [
|
|
356
|
-
|
|
2949
|
+
b("div", {
|
|
357
2950
|
style: { height: `${i}px` }
|
|
358
2951
|
})
|
|
359
2952
|
]
|
|
360
2953
|
});
|
|
361
2954
|
}
|
|
362
|
-
for (let i = this.visibleStartIndex; i <= this.visibleEndIndex && i <
|
|
363
|
-
const
|
|
364
|
-
r.push(this.createListItem(
|
|
2955
|
+
for (let i = this.visibleStartIndex; i <= this.visibleEndIndex && i < e.length; i++) {
|
|
2956
|
+
const o = e[i], a = this.props.getItemId ? this.props.getItemId(o, i) : i, h = t.has(a);
|
|
2957
|
+
r.push(this.createListItem(o, i, h)), s && i < e.length - 1 && r.push(s);
|
|
365
2958
|
}
|
|
366
|
-
if (this.visibleEndIndex <
|
|
2959
|
+
if (this.visibleEndIndex < e.length - 1) {
|
|
367
2960
|
const i = this.totalHeight - (this.virtualItems[this.visibleEndIndex + 1]?.offset || 0);
|
|
368
2961
|
r.push({
|
|
369
2962
|
type: "component",
|
|
@@ -372,7 +2965,7 @@ class $ {
|
|
|
372
2965
|
cleanup: [],
|
|
373
2966
|
props: {},
|
|
374
2967
|
render: () => [
|
|
375
|
-
|
|
2968
|
+
b("div", {
|
|
376
2969
|
style: { height: `${i}px` }
|
|
377
2970
|
})
|
|
378
2971
|
]
|
|
@@ -384,98 +2977,97 @@ class $ {
|
|
|
384
2977
|
* Render regular (non-virtual) content
|
|
385
2978
|
*/
|
|
386
2979
|
renderRegularContent() {
|
|
387
|
-
const
|
|
388
|
-
return
|
|
389
|
-
const h = this.createSectionHeader(
|
|
390
|
-
h && i.push(h),
|
|
391
|
-
const
|
|
392
|
-
i.push(this.createListItem(
|
|
2980
|
+
const e = this.dataSignal(), t = this.sectionsSignal(), s = this.selectedItemsSignal(), r = this.createSeparator(), i = [];
|
|
2981
|
+
return t.length > 0 ? t.forEach((o, a) => {
|
|
2982
|
+
const h = this.createSectionHeader(o, a);
|
|
2983
|
+
h && i.push(h), o.items.forEach((l, d) => {
|
|
2984
|
+
const f = a * 1e3 + d, p = this.props.getItemId ? this.props.getItemId(l, f) : f, N = s.has(p);
|
|
2985
|
+
i.push(this.createListItem(l, f, N)), r && d < o.items.length - 1 && i.push(r);
|
|
393
2986
|
});
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
}) :
|
|
397
|
-
const h = this.props.getItemId ? this.props.getItemId(
|
|
398
|
-
i.push(this.createListItem(
|
|
2987
|
+
const c = this.createSectionFooter(o, a);
|
|
2988
|
+
c && i.push(c);
|
|
2989
|
+
}) : e.forEach((o, a) => {
|
|
2990
|
+
const h = this.props.getItemId ? this.props.getItemId(o, a) : a, c = s.has(h);
|
|
2991
|
+
i.push(this.createListItem(o, a, c)), r && a < e.length - 1 && i.push(r);
|
|
399
2992
|
}), i;
|
|
400
2993
|
}
|
|
401
2994
|
/**
|
|
402
2995
|
* Render the list component
|
|
403
2996
|
*/
|
|
404
2997
|
render() {
|
|
405
|
-
const
|
|
406
|
-
if (
|
|
407
|
-
const
|
|
408
|
-
return
|
|
2998
|
+
const e = this.dataSignal(), t = this.isLoadingSignal();
|
|
2999
|
+
if (t && e.length === 0) {
|
|
3000
|
+
const o = this.createLoadingIndicator();
|
|
3001
|
+
return o ? o.render() : [];
|
|
409
3002
|
}
|
|
410
|
-
if (
|
|
411
|
-
const
|
|
412
|
-
return
|
|
3003
|
+
if (e.length === 0 && !t) {
|
|
3004
|
+
const o = this.createEmptyState();
|
|
3005
|
+
return o ? o.render() : [];
|
|
413
3006
|
}
|
|
414
|
-
const
|
|
415
|
-
if (
|
|
416
|
-
const
|
|
417
|
-
|
|
3007
|
+
const s = this.props.virtualScrolling?.enabled ? this.renderVirtualContent() : this.renderRegularContent();
|
|
3008
|
+
if (t && e.length > 0) {
|
|
3009
|
+
const o = this.createLoadingIndicator();
|
|
3010
|
+
o && s.push(o);
|
|
418
3011
|
}
|
|
419
3012
|
const r = {
|
|
420
3013
|
...this.props,
|
|
421
|
-
children:
|
|
3014
|
+
children: s,
|
|
422
3015
|
onScroll: this.handleListScroll
|
|
423
3016
|
};
|
|
424
|
-
return new
|
|
3017
|
+
return new Et(r).render();
|
|
425
3018
|
}
|
|
426
3019
|
}
|
|
427
|
-
function
|
|
428
|
-
const
|
|
429
|
-
return
|
|
3020
|
+
function F(n) {
|
|
3021
|
+
const e = new At(n);
|
|
3022
|
+
return re(e);
|
|
430
3023
|
}
|
|
431
|
-
const
|
|
3024
|
+
const kt = {
|
|
432
3025
|
/**
|
|
433
3026
|
* Create a simple list from array
|
|
434
3027
|
*/
|
|
435
|
-
simple(
|
|
436
|
-
return
|
|
437
|
-
...
|
|
438
|
-
data:
|
|
439
|
-
renderItem:
|
|
3028
|
+
simple(n, e, t = {}) {
|
|
3029
|
+
return F({
|
|
3030
|
+
...t,
|
|
3031
|
+
data: n,
|
|
3032
|
+
renderItem: e
|
|
440
3033
|
});
|
|
441
3034
|
},
|
|
442
3035
|
/**
|
|
443
3036
|
* Create a sectioned list
|
|
444
3037
|
*/
|
|
445
|
-
sectioned(
|
|
446
|
-
return
|
|
447
|
-
...
|
|
448
|
-
sections:
|
|
449
|
-
renderItem:
|
|
3038
|
+
sectioned(n, e, t = {}) {
|
|
3039
|
+
return F({
|
|
3040
|
+
...t,
|
|
3041
|
+
sections: n,
|
|
3042
|
+
renderItem: e
|
|
450
3043
|
});
|
|
451
3044
|
},
|
|
452
3045
|
/**
|
|
453
3046
|
* Create a virtual scrolling list for large datasets
|
|
454
3047
|
*/
|
|
455
|
-
virtual(
|
|
456
|
-
return
|
|
457
|
-
...
|
|
458
|
-
data:
|
|
459
|
-
renderItem:
|
|
460
|
-
virtualScrolling:
|
|
3048
|
+
virtual(n, e, t, s = {}) {
|
|
3049
|
+
return F({
|
|
3050
|
+
...s,
|
|
3051
|
+
data: n,
|
|
3052
|
+
renderItem: e,
|
|
3053
|
+
virtualScrolling: t
|
|
461
3054
|
});
|
|
462
3055
|
},
|
|
463
3056
|
/**
|
|
464
3057
|
* Create an infinite scrolling list
|
|
465
3058
|
*/
|
|
466
|
-
infinite(
|
|
467
|
-
return
|
|
3059
|
+
infinite(n, e, t, s, r = {}) {
|
|
3060
|
+
return F({
|
|
468
3061
|
...r,
|
|
469
|
-
data:
|
|
470
|
-
renderItem:
|
|
471
|
-
onLoadMore:
|
|
472
|
-
hasMore:
|
|
3062
|
+
data: n,
|
|
3063
|
+
renderItem: e,
|
|
3064
|
+
onLoadMore: t,
|
|
3065
|
+
hasMore: s
|
|
473
3066
|
});
|
|
474
3067
|
}
|
|
475
3068
|
};
|
|
476
3069
|
export {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
3070
|
+
At as E,
|
|
3071
|
+
F as L,
|
|
3072
|
+
kt as a
|
|
480
3073
|
};
|
|
481
|
-
//# sourceMappingURL=List.js.map
|