@pulse-js/core 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -118
- package/dist/index.cjs +346 -62
- package/dist/index.d.cts +167 -31
- package/dist/index.d.ts +167 -31
- package/dist/index.js +338 -61
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -102,7 +102,12 @@ function guard(nameOrFn, fn) {
|
|
|
102
102
|
if (currentId === evaluationId) {
|
|
103
103
|
persistDependencies();
|
|
104
104
|
if (resolved === false) {
|
|
105
|
-
const
|
|
105
|
+
const message = name ? `${name} failed` : "condition failed";
|
|
106
|
+
const reason = {
|
|
107
|
+
code: "GUARD_FAIL",
|
|
108
|
+
message,
|
|
109
|
+
toString: () => message
|
|
110
|
+
};
|
|
106
111
|
state = { status: "fail", reason, lastReason: reason, updatedAt: Date.now() };
|
|
107
112
|
} else if (resolved === void 0) {
|
|
108
113
|
state = { ...state, status: "pending", updatedAt: Date.now() };
|
|
@@ -114,13 +119,22 @@ function guard(nameOrFn, fn) {
|
|
|
114
119
|
}).catch((err) => {
|
|
115
120
|
if (currentId === evaluationId) {
|
|
116
121
|
persistDependencies();
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
let reason;
|
|
123
|
+
if (err && err._pulseFail) {
|
|
124
|
+
reason = err._reason;
|
|
125
|
+
} else {
|
|
126
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
127
|
+
reason = err && err.meta ? {
|
|
128
|
+
code: err.code || "ERROR",
|
|
129
|
+
message,
|
|
130
|
+
meta: err.meta,
|
|
131
|
+
toString: () => message
|
|
132
|
+
} : {
|
|
133
|
+
code: "ERROR",
|
|
134
|
+
message,
|
|
135
|
+
toString: () => message
|
|
136
|
+
};
|
|
137
|
+
}
|
|
124
138
|
state = {
|
|
125
139
|
status: "fail",
|
|
126
140
|
reason,
|
|
@@ -133,7 +147,12 @@ function guard(nameOrFn, fn) {
|
|
|
133
147
|
} else {
|
|
134
148
|
persistDependencies();
|
|
135
149
|
if (result === false) {
|
|
136
|
-
const
|
|
150
|
+
const message = name ? `${name} failed` : "condition failed";
|
|
151
|
+
const reason = {
|
|
152
|
+
code: "GUARD_FAIL",
|
|
153
|
+
message,
|
|
154
|
+
toString: () => message
|
|
155
|
+
};
|
|
137
156
|
state = { status: "fail", reason, lastReason: reason, updatedAt: Date.now() };
|
|
138
157
|
} else if (result === void 0) {
|
|
139
158
|
state = { ...state, status: "pending", updatedAt: Date.now() };
|
|
@@ -162,7 +181,11 @@ function guard(nameOrFn, fn) {
|
|
|
162
181
|
message,
|
|
163
182
|
meta: err.meta,
|
|
164
183
|
toString: () => message
|
|
165
|
-
} :
|
|
184
|
+
} : {
|
|
185
|
+
code: "ERROR",
|
|
186
|
+
message,
|
|
187
|
+
toString: () => message
|
|
188
|
+
};
|
|
166
189
|
state = {
|
|
167
190
|
status: "fail",
|
|
168
191
|
reason,
|
|
@@ -257,9 +280,8 @@ function guard(nameOrFn, fn) {
|
|
|
257
280
|
if (name) {
|
|
258
281
|
registerGuardForHydration(name, g);
|
|
259
282
|
}
|
|
260
|
-
PulseRegistry.register(g);
|
|
261
283
|
evaluate2();
|
|
262
|
-
return g;
|
|
284
|
+
return PulseRegistry.register(g);
|
|
263
285
|
}
|
|
264
286
|
guard.map = function(source2, mapper, name) {
|
|
265
287
|
const guardName = name || `map-${source2._name || "source"}`;
|
|
@@ -268,69 +290,132 @@ guard.map = function(source2, mapper, name) {
|
|
|
268
290
|
return mapper(value);
|
|
269
291
|
});
|
|
270
292
|
};
|
|
293
|
+
guard.select = function(pulseObj, selector, name) {
|
|
294
|
+
const guardName = name || `select-${pulseObj._name || "pulse"}`;
|
|
295
|
+
return guard(guardName, () => {
|
|
296
|
+
return selector(pulseObj);
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
guard.from = function(getValue, options) {
|
|
300
|
+
const name = options?.name || "from-external";
|
|
301
|
+
return guard(name, () => {
|
|
302
|
+
const result = getValue();
|
|
303
|
+
if (result && typeof result === "object" && ("value" in result || "isLoading" in result || "error" in result)) {
|
|
304
|
+
const wrapped = result;
|
|
305
|
+
if (wrapped.isLoading) {
|
|
306
|
+
return void 0;
|
|
307
|
+
}
|
|
308
|
+
if (wrapped.error) {
|
|
309
|
+
guardFail(wrapped.error?.message || "External error");
|
|
310
|
+
}
|
|
311
|
+
return wrapped.value;
|
|
312
|
+
}
|
|
313
|
+
return result;
|
|
314
|
+
});
|
|
315
|
+
};
|
|
271
316
|
|
|
272
317
|
// src/registry.ts
|
|
318
|
+
function generateUID(name, sourceInfo) {
|
|
319
|
+
if (sourceInfo?.file && sourceInfo?.line) {
|
|
320
|
+
return `${sourceInfo.file}:${sourceInfo.line}:${name}`;
|
|
321
|
+
}
|
|
322
|
+
return `pulse:${name}`;
|
|
323
|
+
}
|
|
273
324
|
var Registry = class {
|
|
274
|
-
|
|
325
|
+
targets = /* @__PURE__ */ new Map();
|
|
326
|
+
proxies = /* @__PURE__ */ new Map();
|
|
275
327
|
listeners = /* @__PURE__ */ new Set();
|
|
276
328
|
currentGeneration = 0;
|
|
277
329
|
cleanupScheduled = false;
|
|
330
|
+
hmrDebounce = null;
|
|
278
331
|
/**
|
|
279
|
-
*
|
|
332
|
+
* Registers a unit and returns a stable Identity Proxy.
|
|
333
|
+
*
|
|
334
|
+
* If a unit with the same UID already exists, it updates the internal
|
|
335
|
+
* target of the existing proxy and returns that same proxy.
|
|
336
|
+
*/
|
|
337
|
+
register(unit) {
|
|
338
|
+
const meta = unit;
|
|
339
|
+
const name = meta._name;
|
|
340
|
+
if (!name) return unit;
|
|
341
|
+
const uid = generateUID(name, meta._sourceInfo);
|
|
342
|
+
meta._uid = uid;
|
|
343
|
+
const existingTarget = this.targets.get(uid);
|
|
344
|
+
const existingProxy = this.proxies.get(uid);
|
|
345
|
+
if (existingProxy) {
|
|
346
|
+
if (this.targets.get(uid) !== unit) {
|
|
347
|
+
if (this.currentGeneration === unit._generation) {
|
|
348
|
+
}
|
|
349
|
+
this.targets.set(uid, unit);
|
|
350
|
+
this.notifyListeners(unit, "update");
|
|
351
|
+
}
|
|
352
|
+
return existingProxy;
|
|
353
|
+
}
|
|
354
|
+
this.targets.set(uid, unit);
|
|
355
|
+
const self = this;
|
|
356
|
+
const proxy = new Proxy((() => {
|
|
357
|
+
}), {
|
|
358
|
+
get(_, prop) {
|
|
359
|
+
const target = self.targets.get(uid);
|
|
360
|
+
if (!target) return void 0;
|
|
361
|
+
const value = target[prop];
|
|
362
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
363
|
+
},
|
|
364
|
+
apply(_, thisArg, args) {
|
|
365
|
+
const target = self.targets.get(uid);
|
|
366
|
+
if (typeof target !== "function") return void 0;
|
|
367
|
+
return Reflect.apply(target, thisArg, args);
|
|
368
|
+
},
|
|
369
|
+
// Ensure type checking and other proxy traps work
|
|
370
|
+
getPrototypeOf(_) {
|
|
371
|
+
return Object.getPrototypeOf(self.targets.get(uid) || {});
|
|
372
|
+
},
|
|
373
|
+
has(_, prop) {
|
|
374
|
+
return Reflect.has(self.targets.get(uid) || {}, prop);
|
|
375
|
+
},
|
|
376
|
+
ownKeys(_) {
|
|
377
|
+
return Reflect.ownKeys(self.targets.get(uid) || {});
|
|
378
|
+
},
|
|
379
|
+
getOwnPropertyDescriptor(_, prop) {
|
|
380
|
+
return Reflect.getOwnPropertyDescriptor(self.targets.get(uid) || {}, prop);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
this.proxies.set(uid, proxy);
|
|
384
|
+
this.notifyListeners(unit, "add");
|
|
385
|
+
return proxy;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Schedules cleanup of units that weren't re-registered.
|
|
280
389
|
*/
|
|
281
390
|
scheduleCleanup() {
|
|
282
391
|
if (this.cleanupScheduled) return;
|
|
283
392
|
this.cleanupScheduled = true;
|
|
284
|
-
|
|
393
|
+
if (this.hmrDebounce) clearTimeout(this.hmrDebounce);
|
|
394
|
+
this.hmrDebounce = setTimeout(() => {
|
|
285
395
|
this.cleanupDeadUnits();
|
|
286
396
|
this.cleanupScheduled = false;
|
|
287
|
-
|
|
397
|
+
this.hmrDebounce = null;
|
|
398
|
+
}, 150);
|
|
288
399
|
}
|
|
289
|
-
/**
|
|
290
|
-
* Removes units that weren't re-registered in the current generation.
|
|
291
|
-
* Uses mark-and-sweep: units that were re-registered have current generation,
|
|
292
|
-
* units that weren't are from old generation and should be removed.
|
|
293
|
-
*/
|
|
294
400
|
cleanupDeadUnits() {
|
|
295
|
-
const toDelete = [];
|
|
296
|
-
this.units.forEach((unit, key) => {
|
|
297
|
-
const gen = unit._generation;
|
|
298
|
-
if (gen !== void 0 && gen < this.currentGeneration) {
|
|
299
|
-
toDelete.push(key);
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
toDelete.forEach((key) => this.units.delete(key));
|
|
303
|
-
if (toDelete.length > 0) {
|
|
304
|
-
console.log(`[Pulse] Cleaned up ${toDelete.length} deleted units after HMR`);
|
|
305
|
-
}
|
|
306
401
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
const existingUnit = this.units.get(name);
|
|
317
|
-
if (existingUnit) {
|
|
318
|
-
const existingGen = existingUnit?._generation;
|
|
319
|
-
if (existingGen === this.currentGeneration) {
|
|
320
|
-
unitWithMetadata._generation = this.currentGeneration;
|
|
321
|
-
this.units.set(name, unit);
|
|
322
|
-
this.listeners.forEach((l) => l(unit));
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
this.currentGeneration++;
|
|
326
|
-
this.scheduleCleanup();
|
|
327
|
-
}
|
|
328
|
-
unitWithMetadata._generation = this.currentGeneration;
|
|
329
|
-
this.units.set(name, unit);
|
|
330
|
-
this.listeners.forEach((l) => l(unit));
|
|
402
|
+
notifyListeners(unit, event) {
|
|
403
|
+
this.listeners.forEach((l) => l(unit, event));
|
|
404
|
+
}
|
|
405
|
+
get(nameOrUid) {
|
|
406
|
+
const proxy = this.proxies.get(nameOrUid);
|
|
407
|
+
if (proxy) return proxy;
|
|
408
|
+
const uid = generateUID(nameOrUid);
|
|
409
|
+
return this.proxies.get(uid);
|
|
331
410
|
}
|
|
332
411
|
getAll() {
|
|
333
|
-
return Array.from(this.
|
|
412
|
+
return Array.from(this.proxies.values());
|
|
413
|
+
}
|
|
414
|
+
getAllWithMeta() {
|
|
415
|
+
return Array.from(this.proxies.entries()).map(([uid, unit]) => ({
|
|
416
|
+
unit,
|
|
417
|
+
uid
|
|
418
|
+
}));
|
|
334
419
|
}
|
|
335
420
|
onRegister(listener) {
|
|
336
421
|
this.listeners.add(listener);
|
|
@@ -339,7 +424,8 @@ var Registry = class {
|
|
|
339
424
|
};
|
|
340
425
|
}
|
|
341
426
|
reset() {
|
|
342
|
-
this.
|
|
427
|
+
this.targets.clear();
|
|
428
|
+
this.proxies.clear();
|
|
343
429
|
this.currentGeneration = 0;
|
|
344
430
|
}
|
|
345
431
|
};
|
|
@@ -381,8 +467,192 @@ function source(initialValue, options = {}) {
|
|
|
381
467
|
return () => subscribers.delete(listener);
|
|
382
468
|
};
|
|
383
469
|
s._name = options.name;
|
|
384
|
-
PulseRegistry.register(s);
|
|
385
|
-
|
|
470
|
+
return PulseRegistry.register(s);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// src/signal.ts
|
|
474
|
+
var batchQueue = null;
|
|
475
|
+
var batchDepth = 0;
|
|
476
|
+
function batch(fn) {
|
|
477
|
+
batchDepth++;
|
|
478
|
+
if (!batchQueue) {
|
|
479
|
+
batchQueue = /* @__PURE__ */ new Set();
|
|
480
|
+
}
|
|
481
|
+
try {
|
|
482
|
+
fn();
|
|
483
|
+
} finally {
|
|
484
|
+
batchDepth--;
|
|
485
|
+
if (batchDepth === 0 && batchQueue) {
|
|
486
|
+
const queue = batchQueue;
|
|
487
|
+
batchQueue = null;
|
|
488
|
+
queue.forEach((notify) => notify());
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function scheduleNotification(notify) {
|
|
493
|
+
if (batchQueue) {
|
|
494
|
+
batchQueue.add(notify);
|
|
495
|
+
} else {
|
|
496
|
+
notify();
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function createSignal(initialValue, equals = (a, b) => a === b) {
|
|
500
|
+
let value = initialValue;
|
|
501
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
502
|
+
const dependents = /* @__PURE__ */ new Set();
|
|
503
|
+
const notify = () => {
|
|
504
|
+
subscribers.forEach((sub) => sub(value));
|
|
505
|
+
const deps = Array.from(dependents);
|
|
506
|
+
dependents.clear();
|
|
507
|
+
deps.forEach((dep) => dep.notify());
|
|
508
|
+
};
|
|
509
|
+
const signal = {
|
|
510
|
+
get() {
|
|
511
|
+
const activeGuard = getCurrentGuard();
|
|
512
|
+
if (activeGuard) {
|
|
513
|
+
dependents.add(activeGuard);
|
|
514
|
+
activeGuard.addDependency(signal);
|
|
515
|
+
}
|
|
516
|
+
return value;
|
|
517
|
+
},
|
|
518
|
+
peek() {
|
|
519
|
+
return value;
|
|
520
|
+
},
|
|
521
|
+
set(newValue) {
|
|
522
|
+
if (!equals(value, newValue)) {
|
|
523
|
+
value = newValue;
|
|
524
|
+
scheduleNotification(notify);
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
update(fn) {
|
|
528
|
+
signal.set(fn(value));
|
|
529
|
+
},
|
|
530
|
+
subscribe(listener) {
|
|
531
|
+
subscribers.add(listener);
|
|
532
|
+
return () => subscribers.delete(listener);
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
return signal;
|
|
536
|
+
}
|
|
537
|
+
function effect(fn) {
|
|
538
|
+
let cleanup;
|
|
539
|
+
let disposed = false;
|
|
540
|
+
const run = () => {
|
|
541
|
+
if (disposed) return;
|
|
542
|
+
if (cleanup) cleanup();
|
|
543
|
+
cleanup = fn();
|
|
544
|
+
};
|
|
545
|
+
run();
|
|
546
|
+
return () => {
|
|
547
|
+
disposed = true;
|
|
548
|
+
if (cleanup) cleanup();
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// src/pulse.ts
|
|
553
|
+
var PULSE_META = /* @__PURE__ */ Symbol("PULSE_META");
|
|
554
|
+
function pulse(target, options = {}) {
|
|
555
|
+
const { name, deep = true } = options;
|
|
556
|
+
const signals = /* @__PURE__ */ new Map();
|
|
557
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
558
|
+
const dependents = /* @__PURE__ */ new Set();
|
|
559
|
+
const nestedCache = /* @__PURE__ */ new Map();
|
|
560
|
+
const meta = {
|
|
561
|
+
signals,
|
|
562
|
+
subscribers,
|
|
563
|
+
dependents,
|
|
564
|
+
name,
|
|
565
|
+
target
|
|
566
|
+
};
|
|
567
|
+
function getSignal(key) {
|
|
568
|
+
if (!signals.has(key)) {
|
|
569
|
+
const initialValue = target[key];
|
|
570
|
+
signals.set(key, createSignal(initialValue));
|
|
571
|
+
}
|
|
572
|
+
return signals.get(key);
|
|
573
|
+
}
|
|
574
|
+
function notify() {
|
|
575
|
+
subscribers.forEach((sub) => sub(proxy));
|
|
576
|
+
const deps = Array.from(dependents);
|
|
577
|
+
dependents.clear();
|
|
578
|
+
deps.forEach((dep) => dep.notify());
|
|
579
|
+
}
|
|
580
|
+
function trackAccess() {
|
|
581
|
+
const activeGuard = getCurrentGuard();
|
|
582
|
+
if (activeGuard) {
|
|
583
|
+
dependents.add(activeGuard);
|
|
584
|
+
activeGuard.addDependency(proxy);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
const proxy = new Proxy(target, {
|
|
588
|
+
get(obj, prop) {
|
|
589
|
+
if (prop === PULSE_META) return meta;
|
|
590
|
+
if (prop === "$raw") return target;
|
|
591
|
+
if (prop === "$subscribe") {
|
|
592
|
+
return (listener) => {
|
|
593
|
+
subscribers.add(listener);
|
|
594
|
+
return () => subscribers.delete(listener);
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
if (prop === "$snapshot") {
|
|
598
|
+
return () => ({ ...target });
|
|
599
|
+
}
|
|
600
|
+
const value = obj[prop];
|
|
601
|
+
if (typeof value === "function") {
|
|
602
|
+
return value.bind(proxy);
|
|
603
|
+
}
|
|
604
|
+
trackAccess();
|
|
605
|
+
const signal = getSignal(prop);
|
|
606
|
+
const currentValue = signal.get();
|
|
607
|
+
if (deep && currentValue !== null && typeof currentValue === "object" && !isPulseObject(currentValue)) {
|
|
608
|
+
if (!nestedCache.has(prop)) {
|
|
609
|
+
nestedCache.set(prop, pulse(currentValue, { deep, name: name ? `${name}.${String(prop)}` : void 0 }));
|
|
610
|
+
}
|
|
611
|
+
return nestedCache.get(prop);
|
|
612
|
+
}
|
|
613
|
+
return currentValue;
|
|
614
|
+
},
|
|
615
|
+
set(obj, prop, value) {
|
|
616
|
+
const oldValue = obj[prop];
|
|
617
|
+
if (oldValue === value) return true;
|
|
618
|
+
obj[prop] = value;
|
|
619
|
+
getSignal(prop).set(value);
|
|
620
|
+
notify();
|
|
621
|
+
return true;
|
|
622
|
+
},
|
|
623
|
+
has(obj, prop) {
|
|
624
|
+
if (prop === PULSE_META) return true;
|
|
625
|
+
trackAccess();
|
|
626
|
+
return Reflect.has(obj, prop);
|
|
627
|
+
},
|
|
628
|
+
ownKeys(obj) {
|
|
629
|
+
trackAccess();
|
|
630
|
+
return Reflect.ownKeys(obj);
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
return PulseRegistry.register(proxy);
|
|
634
|
+
}
|
|
635
|
+
function isPulseObject(value) {
|
|
636
|
+
return value !== null && typeof value === "object" && PULSE_META in value;
|
|
637
|
+
}
|
|
638
|
+
function toRaw(pulseObj) {
|
|
639
|
+
return pulseObj.$raw;
|
|
640
|
+
}
|
|
641
|
+
function readonly(pulseObj) {
|
|
642
|
+
return new Proxy(pulseObj, {
|
|
643
|
+
set() {
|
|
644
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
645
|
+
console.warn("[Pulse] Attempted to mutate a readonly pulse object");
|
|
646
|
+
}
|
|
647
|
+
return false;
|
|
648
|
+
},
|
|
649
|
+
deleteProperty() {
|
|
650
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
651
|
+
console.warn("[Pulse] Attempted to delete from a readonly pulse object");
|
|
652
|
+
}
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
});
|
|
386
656
|
}
|
|
387
657
|
|
|
388
658
|
// src/compute.ts
|
|
@@ -450,14 +720,21 @@ var guardExtensions = {
|
|
|
450
720
|
var extendedGuard = Object.assign(guard, guardExtensions);
|
|
451
721
|
export {
|
|
452
722
|
PulseRegistry,
|
|
723
|
+
batch,
|
|
453
724
|
compute,
|
|
725
|
+
createSignal,
|
|
726
|
+
effect,
|
|
454
727
|
evaluate,
|
|
455
728
|
getCurrentGuard,
|
|
456
729
|
extendedGuard as guard,
|
|
457
730
|
guardFail,
|
|
458
731
|
guardOk,
|
|
459
732
|
hydrate,
|
|
733
|
+
isPulseObject,
|
|
734
|
+
pulse,
|
|
735
|
+
readonly,
|
|
460
736
|
registerGuardForHydration,
|
|
461
737
|
runInContext,
|
|
462
|
-
source
|
|
738
|
+
source,
|
|
739
|
+
toRaw
|
|
463
740
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulse-js/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"module": "dist/index.js",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
"build": "bun x tsup src/index.ts --format esm,cjs --dts --clean",
|
|
46
46
|
"dev": "bun x tsup src/index.ts --format esm,cjs --watch --dts",
|
|
47
47
|
"lint": "bun x tsc --noEmit",
|
|
48
|
-
"test": "vitest run"
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"test:v2": "bun test tests/v2.test.ts tests/astro.test.ts tests/tanstack.test.ts",
|
|
50
|
+
"benchmark": "bun run tests/v2-benchmarks.ts"
|
|
49
51
|
},
|
|
50
52
|
"devDependencies": {
|
|
51
53
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|