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