dalila 1.9.21 → 1.9.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -5
- package/dist/components/ui/ui-types.d.ts +8 -8
- package/dist/core/signal.d.ts +9 -1
- package/dist/core/signal.js +63 -87
- package/dist/form/field-array.d.ts +12 -0
- package/dist/form/field-array.js +306 -0
- package/dist/form/form-dom.d.ts +6 -0
- package/dist/form/form-dom.js +52 -0
- package/dist/form/form-types.d.ts +24 -15
- package/dist/form/form.d.ts +7 -53
- package/dist/form/form.js +49 -932
- package/dist/form/index.d.ts +2 -2
- package/dist/form/index.js +1 -2
- package/dist/form/parse-form-data.d.ts +13 -0
- package/dist/form/parse-form-data.js +88 -0
- package/dist/form/path-utils.d.ts +24 -0
- package/dist/form/path-utils.js +91 -0
- package/dist/form/path-watchers.d.ts +23 -0
- package/dist/form/path-watchers.js +82 -0
- package/dist/form/validation-pipeline.d.ts +29 -0
- package/dist/form/validation-pipeline.js +223 -0
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +1 -1
- package/dist/router/location-utils.d.ts +19 -0
- package/dist/router/location-utils.js +60 -0
- package/dist/router/lru-cache.d.ts +17 -0
- package/dist/router/lru-cache.js +63 -0
- package/dist/router/preload-metadata.d.ts +26 -0
- package/dist/router/preload-metadata.js +65 -0
- package/dist/router/router-lifecycle.d.ts +12 -0
- package/dist/router/router-lifecycle.js +31 -0
- package/dist/router/router-mount-lifecycle.d.ts +11 -0
- package/dist/router/router-mount-lifecycle.js +50 -0
- package/dist/router/router-prefetch.d.ts +22 -0
- package/dist/router/router-prefetch.js +86 -0
- package/dist/router/router-preload-cache.d.ts +25 -0
- package/dist/router/router-preload-cache.js +68 -0
- package/dist/router/router-render-utils.d.ts +14 -0
- package/dist/router/router-render-utils.js +11 -0
- package/dist/router/router-validation.d.ts +4 -0
- package/dist/router/router-validation.js +100 -0
- package/dist/router/router-view-composer.d.ts +16 -0
- package/dist/router/router-view-composer.js +41 -0
- package/dist/router/router.d.ts +12 -3
- package/dist/router/router.js +241 -621
- package/dist/runtime/array-directive-dom.d.ts +4 -0
- package/dist/runtime/array-directive-dom.js +30 -0
- package/dist/runtime/bind.js +112 -834
- package/dist/runtime/internal/components/component-props.d.ts +15 -0
- package/dist/runtime/internal/components/component-props.js +69 -0
- package/dist/runtime/internal/components/component-slots.d.ts +10 -0
- package/dist/runtime/internal/components/component-slots.js +68 -0
- package/dist/runtime/internal/list/list-clone-factory.d.ts +17 -0
- package/dist/runtime/internal/list/list-clone-factory.js +35 -0
- package/dist/runtime/internal/list/list-clone-registry.d.ts +12 -0
- package/dist/runtime/internal/list/list-clone-registry.js +43 -0
- package/dist/runtime/internal/list/list-keying.d.ts +13 -0
- package/dist/runtime/internal/list/list-keying.js +65 -0
- package/dist/runtime/internal/list/list-metadata.d.ts +11 -0
- package/dist/runtime/internal/list/list-metadata.js +21 -0
- package/dist/runtime/internal/list/list-reconcile.d.ts +3 -0
- package/dist/runtime/internal/list/list-reconcile.js +25 -0
- package/dist/runtime/internal/list/list-scheduler.d.ts +16 -0
- package/dist/runtime/internal/list/list-scheduler.js +45 -0
- package/dist/runtime/internal/virtual/virtual-list-helpers.d.ts +48 -0
- package/dist/runtime/internal/virtual/virtual-list-helpers.js +291 -0
- package/package.json +6 -5
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
export function readVirtualNumberOption(raw, ctx, label, deps) {
|
|
2
|
+
if (!raw)
|
|
3
|
+
return null;
|
|
4
|
+
const trimmed = raw.trim();
|
|
5
|
+
if (!trimmed)
|
|
6
|
+
return null;
|
|
7
|
+
const asNumber = Number(trimmed);
|
|
8
|
+
if (Number.isFinite(asNumber))
|
|
9
|
+
return asNumber;
|
|
10
|
+
const fromCtx = ctx[trimmed];
|
|
11
|
+
if (fromCtx === undefined) {
|
|
12
|
+
deps.warn(`${label}: "${trimmed}" not found in context`);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const resolved = deps.resolve(fromCtx);
|
|
16
|
+
if (typeof resolved === 'number' && Number.isFinite(resolved))
|
|
17
|
+
return resolved;
|
|
18
|
+
const numericFromString = Number(resolved);
|
|
19
|
+
if (Number.isFinite(numericFromString))
|
|
20
|
+
return numericFromString;
|
|
21
|
+
deps.warn(`${label}: "${trimmed}" must resolve to a finite number`);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
export function readVirtualHeightOption(raw, ctx, deps) {
|
|
25
|
+
if (!raw)
|
|
26
|
+
return null;
|
|
27
|
+
const trimmed = raw.trim();
|
|
28
|
+
if (!trimmed)
|
|
29
|
+
return null;
|
|
30
|
+
const asNumber = Number(trimmed);
|
|
31
|
+
if (Number.isFinite(asNumber))
|
|
32
|
+
return `${asNumber}px`;
|
|
33
|
+
const fromCtx = ctx[trimmed];
|
|
34
|
+
if (fromCtx !== undefined) {
|
|
35
|
+
const resolved = deps.resolve(fromCtx);
|
|
36
|
+
if (typeof resolved === 'number' && Number.isFinite(resolved))
|
|
37
|
+
return `${resolved}px`;
|
|
38
|
+
if (typeof resolved === 'string' && resolved.trim())
|
|
39
|
+
return resolved.trim();
|
|
40
|
+
}
|
|
41
|
+
return trimmed;
|
|
42
|
+
}
|
|
43
|
+
export function readVirtualMeasureOption(raw, ctx, deps) {
|
|
44
|
+
if (!raw)
|
|
45
|
+
return false;
|
|
46
|
+
const trimmed = raw.trim();
|
|
47
|
+
if (!trimmed)
|
|
48
|
+
return false;
|
|
49
|
+
if (trimmed.toLowerCase() === 'auto')
|
|
50
|
+
return true;
|
|
51
|
+
const fromCtx = ctx[trimmed];
|
|
52
|
+
if (fromCtx === undefined)
|
|
53
|
+
return false;
|
|
54
|
+
const resolved = deps.resolve(fromCtx);
|
|
55
|
+
if (resolved === true)
|
|
56
|
+
return true;
|
|
57
|
+
if (typeof resolved === 'string' && resolved.trim().toLowerCase() === 'auto')
|
|
58
|
+
return true;
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
export function readVirtualCallbackOption(raw, ctx, label, deps) {
|
|
62
|
+
if (!raw)
|
|
63
|
+
return null;
|
|
64
|
+
const trimmed = raw.trim();
|
|
65
|
+
if (!trimmed)
|
|
66
|
+
return null;
|
|
67
|
+
const fromCtx = ctx[trimmed];
|
|
68
|
+
if (fromCtx === undefined) {
|
|
69
|
+
deps.warn(`${label}: "${trimmed}" not found in context`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
if (typeof fromCtx === 'function' && !deps.isSignal(fromCtx)) {
|
|
73
|
+
return fromCtx;
|
|
74
|
+
}
|
|
75
|
+
if (deps.isSignal(fromCtx)) {
|
|
76
|
+
const resolved = fromCtx();
|
|
77
|
+
if (typeof resolved === 'function') {
|
|
78
|
+
return resolved;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
deps.warn(`${label}: "${trimmed}" must resolve to a function`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
export function createVirtualSpacer(template, kind) {
|
|
85
|
+
const spacer = template.cloneNode(false);
|
|
86
|
+
spacer.removeAttribute('id');
|
|
87
|
+
spacer.removeAttribute('class');
|
|
88
|
+
for (const attr of Array.from(spacer.attributes)) {
|
|
89
|
+
if (attr.name.startsWith('d-')) {
|
|
90
|
+
spacer.removeAttribute(attr.name);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
spacer.textContent = '';
|
|
94
|
+
spacer.setAttribute('aria-hidden', 'true');
|
|
95
|
+
spacer.setAttribute('data-dalila-virtual-spacer', kind);
|
|
96
|
+
spacer.style.height = '0px';
|
|
97
|
+
spacer.style.margin = '0';
|
|
98
|
+
spacer.style.padding = '0';
|
|
99
|
+
spacer.style.border = '0';
|
|
100
|
+
spacer.style.pointerEvents = 'none';
|
|
101
|
+
spacer.style.visibility = 'hidden';
|
|
102
|
+
spacer.style.listStyle = 'none';
|
|
103
|
+
return spacer;
|
|
104
|
+
}
|
|
105
|
+
const virtualScrollRestoreCache = new Map();
|
|
106
|
+
const VIRTUAL_SCROLL_RESTORE_CACHE_MAX_ENTRIES = 256;
|
|
107
|
+
export function getVirtualScrollRestoreValue(key) {
|
|
108
|
+
const value = virtualScrollRestoreCache.get(key);
|
|
109
|
+
if (value === undefined)
|
|
110
|
+
return undefined;
|
|
111
|
+
virtualScrollRestoreCache.delete(key);
|
|
112
|
+
virtualScrollRestoreCache.set(key, value);
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
export function setVirtualScrollRestoreValue(key, value) {
|
|
116
|
+
virtualScrollRestoreCache.delete(key);
|
|
117
|
+
virtualScrollRestoreCache.set(key, value);
|
|
118
|
+
while (virtualScrollRestoreCache.size > VIRTUAL_SCROLL_RESTORE_CACHE_MAX_ENTRIES) {
|
|
119
|
+
const oldestKey = virtualScrollRestoreCache.keys().next().value;
|
|
120
|
+
if (!oldestKey)
|
|
121
|
+
break;
|
|
122
|
+
virtualScrollRestoreCache.delete(oldestKey);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export function clampVirtual(value, min, max) {
|
|
126
|
+
return Math.max(min, Math.min(max, value));
|
|
127
|
+
}
|
|
128
|
+
export function getElementPositionPath(el) {
|
|
129
|
+
const parts = [];
|
|
130
|
+
let current = el;
|
|
131
|
+
while (current) {
|
|
132
|
+
const tag = current.tagName.toLowerCase();
|
|
133
|
+
const parentEl = current.parentElement;
|
|
134
|
+
if (!parentEl) {
|
|
135
|
+
parts.push(tag);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
let index = 1;
|
|
139
|
+
let sib = current.previousElementSibling;
|
|
140
|
+
while (sib) {
|
|
141
|
+
index++;
|
|
142
|
+
sib = sib.previousElementSibling;
|
|
143
|
+
}
|
|
144
|
+
parts.push(`${tag}:${index}`);
|
|
145
|
+
current = parentEl;
|
|
146
|
+
}
|
|
147
|
+
return parts.reverse().join('>');
|
|
148
|
+
}
|
|
149
|
+
const virtualRestoreDocumentIds = new WeakMap();
|
|
150
|
+
let nextVirtualRestoreDocumentId = 0;
|
|
151
|
+
function getVirtualRestoreDocumentId(doc) {
|
|
152
|
+
const existing = virtualRestoreDocumentIds.get(doc);
|
|
153
|
+
if (existing !== undefined)
|
|
154
|
+
return existing;
|
|
155
|
+
const next = ++nextVirtualRestoreDocumentId;
|
|
156
|
+
virtualRestoreDocumentIds.set(doc, next);
|
|
157
|
+
return next;
|
|
158
|
+
}
|
|
159
|
+
export function getVirtualRestoreKey(doc, templatePath, scrollContainer, bindingName, keyBinding) {
|
|
160
|
+
const locationPath = typeof window !== 'undefined'
|
|
161
|
+
? `${window.location.pathname}${window.location.search}`
|
|
162
|
+
: '';
|
|
163
|
+
const containerIdentity = scrollContainer?.id
|
|
164
|
+
? `#${scrollContainer.id}`
|
|
165
|
+
: (scrollContainer ? getElementPositionPath(scrollContainer) : '');
|
|
166
|
+
const docId = getVirtualRestoreDocumentId(doc);
|
|
167
|
+
return `${docId}|${locationPath}|${bindingName}|${keyBinding ?? ''}|${containerIdentity}|${templatePath}`;
|
|
168
|
+
}
|
|
169
|
+
export class VirtualHeightsIndex {
|
|
170
|
+
constructor(itemCount, estimatedHeight) {
|
|
171
|
+
this.itemCount = 0;
|
|
172
|
+
this.estimatedHeight = 1;
|
|
173
|
+
this.tree = [0];
|
|
174
|
+
this.overrides = new Map();
|
|
175
|
+
this.reset(itemCount, estimatedHeight);
|
|
176
|
+
}
|
|
177
|
+
get count() {
|
|
178
|
+
return this.itemCount;
|
|
179
|
+
}
|
|
180
|
+
snapshotOverrides() {
|
|
181
|
+
return new Map(this.overrides);
|
|
182
|
+
}
|
|
183
|
+
reset(itemCount, estimatedHeight, seed) {
|
|
184
|
+
this.itemCount = Number.isFinite(itemCount) ? Math.max(0, Math.floor(itemCount)) : 0;
|
|
185
|
+
this.estimatedHeight = Number.isFinite(estimatedHeight) ? Math.max(1, estimatedHeight) : 1;
|
|
186
|
+
this.tree = new Array(this.itemCount + 1).fill(0);
|
|
187
|
+
this.overrides.clear();
|
|
188
|
+
for (let i = 0; i < this.itemCount; i++) {
|
|
189
|
+
this.addAt(i + 1, this.estimatedHeight);
|
|
190
|
+
}
|
|
191
|
+
if (!seed)
|
|
192
|
+
return;
|
|
193
|
+
for (const [index, height] of seed.entries()) {
|
|
194
|
+
if (index < 0 || index >= this.itemCount)
|
|
195
|
+
continue;
|
|
196
|
+
this.set(index, height);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
set(index, height) {
|
|
200
|
+
if (!Number.isFinite(height) || height <= 0)
|
|
201
|
+
return false;
|
|
202
|
+
if (index < 0 || index >= this.itemCount)
|
|
203
|
+
return false;
|
|
204
|
+
const next = Math.max(1, height);
|
|
205
|
+
const current = this.get(index);
|
|
206
|
+
if (Math.abs(next - current) < 0.5)
|
|
207
|
+
return false;
|
|
208
|
+
this.addAt(index + 1, next - current);
|
|
209
|
+
if (Math.abs(next - this.estimatedHeight) < 0.5) {
|
|
210
|
+
this.overrides.delete(index);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
this.overrides.set(index, next);
|
|
214
|
+
}
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
get(index) {
|
|
218
|
+
if (index < 0 || index >= this.itemCount)
|
|
219
|
+
return this.estimatedHeight;
|
|
220
|
+
return this.overrides.get(index) ?? this.estimatedHeight;
|
|
221
|
+
}
|
|
222
|
+
prefix(endExclusive) {
|
|
223
|
+
if (endExclusive <= 0)
|
|
224
|
+
return 0;
|
|
225
|
+
const clampedEnd = Math.min(this.itemCount, Math.max(0, Math.floor(endExclusive)));
|
|
226
|
+
let i = clampedEnd;
|
|
227
|
+
let sum = 0;
|
|
228
|
+
while (i > 0) {
|
|
229
|
+
sum += this.tree[i];
|
|
230
|
+
i -= i & -i;
|
|
231
|
+
}
|
|
232
|
+
return sum;
|
|
233
|
+
}
|
|
234
|
+
total() {
|
|
235
|
+
return this.prefix(this.itemCount);
|
|
236
|
+
}
|
|
237
|
+
lowerBound(target) {
|
|
238
|
+
if (this.itemCount === 0 || target <= 0)
|
|
239
|
+
return 0;
|
|
240
|
+
let idx = 0;
|
|
241
|
+
let bit = 1;
|
|
242
|
+
while ((bit << 1) <= this.itemCount)
|
|
243
|
+
bit <<= 1;
|
|
244
|
+
let sum = 0;
|
|
245
|
+
while (bit > 0) {
|
|
246
|
+
const next = idx + bit;
|
|
247
|
+
if (next <= this.itemCount && sum + this.tree[next] < target) {
|
|
248
|
+
idx = next;
|
|
249
|
+
sum += this.tree[next];
|
|
250
|
+
}
|
|
251
|
+
bit >>= 1;
|
|
252
|
+
}
|
|
253
|
+
return Math.min(this.itemCount, idx);
|
|
254
|
+
}
|
|
255
|
+
indexAtOffset(offset) {
|
|
256
|
+
if (this.itemCount === 0)
|
|
257
|
+
return 0;
|
|
258
|
+
if (!Number.isFinite(offset) || offset <= 0)
|
|
259
|
+
return 0;
|
|
260
|
+
const totalHeight = this.total();
|
|
261
|
+
if (offset >= totalHeight)
|
|
262
|
+
return this.itemCount - 1;
|
|
263
|
+
const idx = this.lowerBound(offset + 0.0001);
|
|
264
|
+
return clampVirtual(idx, 0, this.itemCount - 1);
|
|
265
|
+
}
|
|
266
|
+
addAt(treeIndex, delta) {
|
|
267
|
+
let i = treeIndex;
|
|
268
|
+
while (i <= this.itemCount) {
|
|
269
|
+
this.tree[i] += delta;
|
|
270
|
+
i += i & -i;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
export function readVirtualListApi(target) {
|
|
275
|
+
if (!target)
|
|
276
|
+
return null;
|
|
277
|
+
return target.__dalilaVirtualList ?? null;
|
|
278
|
+
}
|
|
279
|
+
export function setVirtualListApi(target, api) {
|
|
280
|
+
if (!target)
|
|
281
|
+
return;
|
|
282
|
+
target.__dalilaVirtualList = api;
|
|
283
|
+
}
|
|
284
|
+
export function clearVirtualListApi(target, api) {
|
|
285
|
+
if (!target)
|
|
286
|
+
return;
|
|
287
|
+
const host = target;
|
|
288
|
+
if (host.__dalilaVirtualList === api) {
|
|
289
|
+
delete host.__dalilaVirtualList;
|
|
290
|
+
}
|
|
291
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dalila",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.22",
|
|
4
4
|
"description": "DOM-first reactive framework based on signals",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"test": "npm run build && node --experimental-strip-types --test --test-concurrency=1 tests/**/*.test.ts",
|
|
104
104
|
"test:typecheck": "npx tsc -p tests/tsconfig.json",
|
|
105
105
|
"test:e2e": "npm run build && playwright test",
|
|
106
|
-
"test:watch": "
|
|
106
|
+
"test:watch": "npm run build && node --watch --experimental-strip-types --test --test-concurrency=1 tests/**/*.test.ts",
|
|
107
107
|
"clean": "rm -rf dist",
|
|
108
108
|
"devtools:firefox:run": "npx web-ext run --source-dir devtools-extension --devtools",
|
|
109
109
|
"devtools:firefox:build": "npx web-ext build --source-dir devtools-extension --artifacts-dir devtools-extension/dist --overwrite-dest"
|
|
@@ -118,13 +118,14 @@
|
|
|
118
118
|
],
|
|
119
119
|
"author": "Everton Da Silva Vieira",
|
|
120
120
|
"license": "MIT",
|
|
121
|
+
"engines": {
|
|
122
|
+
"node": ">=22.6.0"
|
|
123
|
+
},
|
|
121
124
|
"devDependencies": {
|
|
122
125
|
"@playwright/test": "^1.57.0",
|
|
123
|
-
"@types/jest": "^29.5.0",
|
|
124
126
|
"@types/node": "^20.0.0",
|
|
125
127
|
"chokidar": "^3.6.0",
|
|
126
|
-
"
|
|
127
|
-
"jest-environment-jsdom": "^29.5.0",
|
|
128
|
+
"jsdom": "^28.1.0",
|
|
128
129
|
"typescript": "^5.9.3"
|
|
129
130
|
},
|
|
130
131
|
"files": [
|