@getforma/core 1.1.0 → 1.2.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/dist/{chunk-JRQNDXX7.cjs → chunk-E3FV2VSU.cjs} +43 -43
- package/dist/{chunk-JRQNDXX7.cjs.map → chunk-E3FV2VSU.cjs.map} +1 -1
- package/dist/{chunk-XLVBYXOU.js → chunk-ETPJTPYD.js} +6 -3
- package/dist/chunk-ETPJTPYD.js.map +1 -0
- package/dist/{chunk-W7OUWVRA.cjs → chunk-H7MDUHS5.cjs} +6 -2
- package/dist/chunk-H7MDUHS5.cjs.map +1 -0
- package/dist/{chunk-2Y5US35K.cjs → chunk-KUXNZ5MG.cjs} +12 -12
- package/dist/{chunk-2Y5US35K.cjs.map → chunk-KUXNZ5MG.cjs.map} +1 -1
- package/dist/{chunk-INNOI6TG.js → chunk-Y3A2EVVS.js} +3 -3
- package/dist/{chunk-INNOI6TG.js.map → chunk-Y3A2EVVS.js.map} +1 -1
- package/dist/{chunk-MIOMT2CB.js → chunk-YRNYOZF3.js} +4 -4
- package/dist/{chunk-MIOMT2CB.js.map → chunk-YRNYOZF3.js.map} +1 -1
- package/dist/formajs.global.js +176 -52
- package/dist/formajs.global.js.map +1 -1
- package/dist/http.cjs +11 -11
- package/dist/http.js +2 -2
- package/dist/index.cjs +259 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +204 -83
- package/dist/index.js.map +1 -1
- package/dist/runtime.cjs +29 -29
- package/dist/runtime.js +3 -3
- package/dist/server.cjs +7 -7
- package/dist/server.js +2 -2
- package/dist/tc39-compat.cjs +3 -3
- package/dist/tc39-compat.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-W7OUWVRA.cjs.map +0 -1
- package/dist/chunk-XLVBYXOU.js.map +0 -1
package/dist/formajs.global.js
CHANGED
|
@@ -625,6 +625,9 @@ var FormaJS = (() => {
|
|
|
625
625
|
|
|
626
626
|
// src/reactive/signal.ts
|
|
627
627
|
var signalNames = /* @__PURE__ */ new WeakMap();
|
|
628
|
+
function value(v) {
|
|
629
|
+
return () => v;
|
|
630
|
+
}
|
|
628
631
|
function applySignalSet(s, v, equals) {
|
|
629
632
|
if (typeof v !== "function") {
|
|
630
633
|
if (!equals) {
|
|
@@ -3156,6 +3159,19 @@ var FormaJS = (() => {
|
|
|
3156
3159
|
function createStore(initial) {
|
|
3157
3160
|
const signals = /* @__PURE__ */ new Map();
|
|
3158
3161
|
const children2 = /* @__PURE__ */ new Map();
|
|
3162
|
+
const arrayVersions = /* @__PURE__ */ new Map();
|
|
3163
|
+
function getArrayVersion(path) {
|
|
3164
|
+
let p = arrayVersions.get(path);
|
|
3165
|
+
if (!p) {
|
|
3166
|
+
p = createSignal(0);
|
|
3167
|
+
arrayVersions.set(path, p);
|
|
3168
|
+
}
|
|
3169
|
+
return p;
|
|
3170
|
+
}
|
|
3171
|
+
function bumpArrayVersion(path) {
|
|
3172
|
+
const p = arrayVersions.get(path);
|
|
3173
|
+
if (p) p[1]((n) => n + 1);
|
|
3174
|
+
}
|
|
3159
3175
|
function registerChild(path) {
|
|
3160
3176
|
const lastDot = path.lastIndexOf(".");
|
|
3161
3177
|
if (lastDot === -1) return;
|
|
@@ -3187,14 +3203,37 @@ var FormaJS = (() => {
|
|
|
3187
3203
|
}
|
|
3188
3204
|
childSet.clear();
|
|
3189
3205
|
}
|
|
3206
|
+
function lastSegment(path) {
|
|
3207
|
+
const d = path.lastIndexOf(".");
|
|
3208
|
+
return d === -1 ? path : path.substring(d + 1);
|
|
3209
|
+
}
|
|
3210
|
+
function setLiteral(pair, v) {
|
|
3211
|
+
pair[1](typeof v === "function" ? value(v) : v);
|
|
3212
|
+
}
|
|
3213
|
+
function reconcileChildren(parentPath, rawParent) {
|
|
3214
|
+
const set = children2.get(parentPath);
|
|
3215
|
+
if (!set) return;
|
|
3216
|
+
for (const childPath of set) {
|
|
3217
|
+
const key = lastSegment(childPath);
|
|
3218
|
+
const nv = rawParent[key];
|
|
3219
|
+
const pair = signals.get(childPath);
|
|
3220
|
+
if (pair) setLiteral(pair, nv);
|
|
3221
|
+
if (nv != null && typeof nv === "object") {
|
|
3222
|
+
reconcileChildren(childPath, nv);
|
|
3223
|
+
} else {
|
|
3224
|
+
invalidateChildren(childPath);
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3190
3228
|
function wrap(raw, basePath) {
|
|
3191
3229
|
if (!shouldWrap(raw)) return raw;
|
|
3192
|
-
|
|
3193
|
-
if (
|
|
3230
|
+
let byPath = proxyCache.get(raw);
|
|
3231
|
+
if (byPath) {
|
|
3232
|
+
const hit = byPath.get(basePath);
|
|
3233
|
+
if (hit) return hit;
|
|
3234
|
+
}
|
|
3194
3235
|
const isArr = Array.isArray(raw);
|
|
3195
3236
|
const basePrefix = basePath ? basePath + "." : "";
|
|
3196
|
-
let lastKey = "";
|
|
3197
|
-
let lastSignal;
|
|
3198
3237
|
const proxy = new Proxy(raw, {
|
|
3199
3238
|
// -------------------------------------------------------------------
|
|
3200
3239
|
// GET
|
|
@@ -3215,12 +3254,10 @@ var FormaJS = (() => {
|
|
|
3215
3254
|
(a) => a != null && typeof a === "object" && a[RAW] ? a[RAW] : a
|
|
3216
3255
|
);
|
|
3217
3256
|
result = target[key].apply(target, rawArgs);
|
|
3218
|
-
|
|
3219
|
-
const
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
);
|
|
3223
|
-
setLen(target.length);
|
|
3257
|
+
reconcileChildren(basePath, target);
|
|
3258
|
+
const lenPair = signals.get(basePrefix + "length");
|
|
3259
|
+
if (lenPair) lenPair[1](target.length);
|
|
3260
|
+
if (basePath) bumpArrayVersion(basePath);
|
|
3224
3261
|
});
|
|
3225
3262
|
return result;
|
|
3226
3263
|
};
|
|
@@ -3231,15 +3268,11 @@ var FormaJS = (() => {
|
|
|
3231
3268
|
return target.length;
|
|
3232
3269
|
}
|
|
3233
3270
|
const value2 = Reflect.get(target, prop);
|
|
3234
|
-
|
|
3235
|
-
if (key === lastKey && lastSignal) {
|
|
3236
|
-
pair = lastSignal;
|
|
3237
|
-
} else {
|
|
3238
|
-
pair = getSignal(childPath, value2);
|
|
3239
|
-
lastKey = key;
|
|
3240
|
-
lastSignal = pair;
|
|
3241
|
-
}
|
|
3271
|
+
const pair = getSignal(childPath, value2);
|
|
3242
3272
|
pair[0]();
|
|
3273
|
+
if (Array.isArray(value2)) {
|
|
3274
|
+
getArrayVersion(childPath)[0]();
|
|
3275
|
+
}
|
|
3243
3276
|
if (shouldWrap(value2)) {
|
|
3244
3277
|
return wrap(value2, childPath);
|
|
3245
3278
|
}
|
|
@@ -3255,9 +3288,11 @@ var FormaJS = (() => {
|
|
|
3255
3288
|
const key = String(prop);
|
|
3256
3289
|
const childPath = basePrefix + key;
|
|
3257
3290
|
const rawValue = value2 != null && typeof value2 === "object" && value2[RAW] ? value2[RAW] : value2;
|
|
3291
|
+
const oldRaw = Reflect.get(target, prop);
|
|
3258
3292
|
Reflect.set(target, prop, rawValue);
|
|
3259
|
-
if (rawValue != null && typeof rawValue === "object") {
|
|
3293
|
+
if (rawValue != null && typeof rawValue === "object" && oldRaw !== rawValue) {
|
|
3260
3294
|
invalidateChildren(childPath);
|
|
3295
|
+
evictProxy(oldRaw, childPath);
|
|
3261
3296
|
}
|
|
3262
3297
|
if (isArr && key !== "length") {
|
|
3263
3298
|
const lengthPath = basePrefix + "length";
|
|
@@ -3266,6 +3301,12 @@ var FormaJS = (() => {
|
|
|
3266
3301
|
lenPair[1](target.length);
|
|
3267
3302
|
}
|
|
3268
3303
|
}
|
|
3304
|
+
if (isArr && key === "length") {
|
|
3305
|
+
batch(() => {
|
|
3306
|
+
reconcileChildren(basePath, target);
|
|
3307
|
+
if (basePath) bumpArrayVersion(basePath);
|
|
3308
|
+
});
|
|
3309
|
+
}
|
|
3269
3310
|
const [, setter2] = getSignal(childPath, rawValue);
|
|
3270
3311
|
setter2(rawValue);
|
|
3271
3312
|
return true;
|
|
@@ -3304,24 +3345,30 @@ var FormaJS = (() => {
|
|
|
3304
3345
|
}
|
|
3305
3346
|
const key = String(prop);
|
|
3306
3347
|
const childPath = basePrefix + key;
|
|
3348
|
+
const oldRaw = Reflect.get(target, prop);
|
|
3307
3349
|
const result = Reflect.deleteProperty(target, prop);
|
|
3350
|
+
const delPair = signals.get(childPath);
|
|
3351
|
+
if (delPair) delPair[1](void 0);
|
|
3352
|
+
evictProxy(oldRaw, childPath);
|
|
3308
3353
|
invalidateChildren(childPath);
|
|
3309
|
-
signals.delete(childPath);
|
|
3310
|
-
const parentPath = basePath;
|
|
3311
|
-
if (parentPath !== void 0) {
|
|
3312
|
-
const parentSet = children2.get(parentPath);
|
|
3313
|
-
if (parentSet) {
|
|
3314
|
-
parentSet.delete(childPath);
|
|
3315
|
-
if (parentSet.size === 0) children2.delete(parentPath);
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
children2.delete(childPath);
|
|
3319
3354
|
return result;
|
|
3320
3355
|
}
|
|
3321
3356
|
});
|
|
3322
|
-
|
|
3357
|
+
if (!byPath) {
|
|
3358
|
+
byPath = /* @__PURE__ */ new Map();
|
|
3359
|
+
proxyCache.set(raw, byPath);
|
|
3360
|
+
}
|
|
3361
|
+
byPath.set(basePath, proxy);
|
|
3323
3362
|
return proxy;
|
|
3324
3363
|
}
|
|
3364
|
+
function evictProxy(oldRaw, path) {
|
|
3365
|
+
if (oldRaw == null || typeof oldRaw !== "object") return;
|
|
3366
|
+
const om = proxyCache.get(oldRaw);
|
|
3367
|
+
if (om) {
|
|
3368
|
+
om.delete(path);
|
|
3369
|
+
if (om.size === 0) proxyCache.delete(oldRaw);
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3325
3372
|
const rootProxy = wrap(initial, "");
|
|
3326
3373
|
function getCurrentSnapshot() {
|
|
3327
3374
|
return untrack(() => deepClone(initial));
|
|
@@ -3338,10 +3385,24 @@ var FormaJS = (() => {
|
|
|
3338
3385
|
}
|
|
3339
3386
|
|
|
3340
3387
|
// src/state/history.ts
|
|
3388
|
+
function cloneEntry(v, seen) {
|
|
3389
|
+
if (v === null || typeof v !== "object") return v;
|
|
3390
|
+
const proto = Object.getPrototypeOf(v);
|
|
3391
|
+
if (!Array.isArray(v) && proto !== Object.prototype && proto !== null) return v;
|
|
3392
|
+
if (!seen) seen = /* @__PURE__ */ new WeakSet();
|
|
3393
|
+
if (seen.has(v)) return v;
|
|
3394
|
+
seen.add(v);
|
|
3395
|
+
if (Array.isArray(v)) return v.map((i) => cloneEntry(i, seen));
|
|
3396
|
+
const out = {};
|
|
3397
|
+
for (const k of Object.keys(v)) {
|
|
3398
|
+
out[k] = cloneEntry(v[k], seen);
|
|
3399
|
+
}
|
|
3400
|
+
return out;
|
|
3401
|
+
}
|
|
3341
3402
|
function createHistory(source, options) {
|
|
3342
3403
|
const [sourceGet, sourceSet] = source;
|
|
3343
|
-
const maxLength = options?.maxLength ?? 100;
|
|
3344
|
-
let _stack = [sourceGet()];
|
|
3404
|
+
const maxLength = Math.max(1, options?.maxLength ?? 100);
|
|
3405
|
+
let _stack = [cloneEntry(sourceGet())];
|
|
3345
3406
|
let _cursor = 0;
|
|
3346
3407
|
const [stackSignal, setStackSignal] = createSignal([..._stack]);
|
|
3347
3408
|
const [cursorSignal, setCursorSignal] = createSignal(_cursor);
|
|
@@ -3353,45 +3414,52 @@ var FormaJS = (() => {
|
|
|
3353
3414
|
setStackLenSignal(_stack.length);
|
|
3354
3415
|
});
|
|
3355
3416
|
}
|
|
3356
|
-
|
|
3417
|
+
const NONE = /* @__PURE__ */ Symbol("none");
|
|
3418
|
+
let _expected = NONE;
|
|
3357
3419
|
let isFirstRun = true;
|
|
3358
|
-
internalEffect(() => {
|
|
3420
|
+
const disposeEffect = internalEffect(() => {
|
|
3359
3421
|
const value2 = sourceGet();
|
|
3360
3422
|
if (isFirstRun) {
|
|
3361
3423
|
isFirstRun = false;
|
|
3362
3424
|
return;
|
|
3363
3425
|
}
|
|
3364
|
-
if (
|
|
3365
|
-
|
|
3426
|
+
if (_expected !== NONE && Object.is(value2, _expected)) {
|
|
3427
|
+
_expected = NONE;
|
|
3366
3428
|
return;
|
|
3367
3429
|
}
|
|
3430
|
+
_expected = NONE;
|
|
3368
3431
|
_stack = _stack.slice(0, _cursor + 1);
|
|
3369
|
-
_stack.push(value2);
|
|
3432
|
+
_stack.push(cloneEntry(value2));
|
|
3370
3433
|
if (_stack.length > maxLength) {
|
|
3371
3434
|
_stack.splice(0, _stack.length - maxLength);
|
|
3372
3435
|
}
|
|
3373
3436
|
_cursor = _stack.length - 1;
|
|
3374
3437
|
syncSignals();
|
|
3375
3438
|
});
|
|
3439
|
+
const destroy = () => {
|
|
3440
|
+
disposeEffect();
|
|
3441
|
+
};
|
|
3376
3442
|
const canUndo = () => cursorSignal() > 0;
|
|
3377
3443
|
const canRedo = () => cursorSignal() < stackLenSignal() - 1;
|
|
3378
3444
|
const undo = () => {
|
|
3379
3445
|
if (_cursor <= 0) return;
|
|
3380
3446
|
_cursor--;
|
|
3381
|
-
|
|
3382
|
-
|
|
3447
|
+
const restored = cloneEntry(_stack[_cursor]);
|
|
3448
|
+
_expected = restored;
|
|
3449
|
+
sourceSet(restored);
|
|
3383
3450
|
syncSignals();
|
|
3384
3451
|
};
|
|
3385
3452
|
const redo = () => {
|
|
3386
3453
|
if (_cursor >= _stack.length - 1) return;
|
|
3387
3454
|
_cursor++;
|
|
3388
|
-
|
|
3389
|
-
|
|
3455
|
+
const restored = cloneEntry(_stack[_cursor]);
|
|
3456
|
+
_expected = restored;
|
|
3457
|
+
sourceSet(restored);
|
|
3390
3458
|
syncSignals();
|
|
3391
3459
|
};
|
|
3392
3460
|
const clear = () => {
|
|
3393
3461
|
const currentValue = sourceGet();
|
|
3394
|
-
_stack = [currentValue];
|
|
3462
|
+
_stack = [cloneEntry(currentValue)];
|
|
3395
3463
|
_cursor = 0;
|
|
3396
3464
|
syncSignals();
|
|
3397
3465
|
};
|
|
@@ -3402,35 +3470,91 @@ var FormaJS = (() => {
|
|
|
3402
3470
|
canRedo,
|
|
3403
3471
|
history: () => stackSignal(),
|
|
3404
3472
|
cursor: () => cursorSignal(),
|
|
3405
|
-
clear
|
|
3473
|
+
clear,
|
|
3474
|
+
destroy
|
|
3406
3475
|
};
|
|
3407
3476
|
}
|
|
3408
3477
|
|
|
3409
3478
|
// src/state/persist.ts
|
|
3479
|
+
var ENVELOPE_TAG = "$forma:v";
|
|
3410
3480
|
function persist(source, key, options) {
|
|
3411
3481
|
const [sourceGet, sourceSet] = source;
|
|
3412
3482
|
const storage = options?.storage ?? globalThis.localStorage;
|
|
3413
3483
|
const serialize = options?.serialize ?? JSON.stringify;
|
|
3414
3484
|
const deserialize = options?.deserialize ?? JSON.parse;
|
|
3415
3485
|
const validate = options?.validate;
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3486
|
+
const version = options?.version;
|
|
3487
|
+
const migrate = options?.migrate;
|
|
3488
|
+
const onError2 = options?.onError;
|
|
3489
|
+
let writing = false;
|
|
3490
|
+
function unwrap(stored) {
|
|
3491
|
+
const parsed = deserialize(stored);
|
|
3492
|
+
if (parsed != null && typeof parsed === "object" && Object.prototype.hasOwnProperty.call(parsed, ENVELOPE_TAG)) {
|
|
3493
|
+
const env = parsed;
|
|
3494
|
+
return { value: env.value, version: Number(env[ENVELOPE_TAG]) };
|
|
3495
|
+
}
|
|
3496
|
+
return { value: parsed, version: 0 };
|
|
3497
|
+
}
|
|
3498
|
+
function hydrate() {
|
|
3499
|
+
let stored;
|
|
3500
|
+
try {
|
|
3501
|
+
stored = storage.getItem(key);
|
|
3502
|
+
} catch (err) {
|
|
3503
|
+
onError2?.(err, "hydrate");
|
|
3504
|
+
return;
|
|
3505
|
+
}
|
|
3506
|
+
if (stored === null) return;
|
|
3507
|
+
try {
|
|
3508
|
+
const { value: raw, version: storedVersion } = unwrap(stored);
|
|
3509
|
+
let value2 = raw;
|
|
3510
|
+
if (version !== void 0 && storedVersion < version) {
|
|
3511
|
+
if (!migrate) return;
|
|
3512
|
+
try {
|
|
3513
|
+
value2 = migrate(raw, storedVersion);
|
|
3514
|
+
} catch (err) {
|
|
3515
|
+
onError2?.(err, "migrate");
|
|
3516
|
+
return;
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3420
3519
|
if (!validate || validate(value2)) {
|
|
3421
|
-
|
|
3520
|
+
writing = true;
|
|
3521
|
+
try {
|
|
3522
|
+
sourceSet(value2);
|
|
3523
|
+
} finally {
|
|
3524
|
+
writing = false;
|
|
3525
|
+
}
|
|
3422
3526
|
}
|
|
3527
|
+
} catch (err) {
|
|
3528
|
+
onError2?.(err, "hydrate");
|
|
3423
3529
|
}
|
|
3424
|
-
} catch {
|
|
3425
3530
|
}
|
|
3426
|
-
|
|
3531
|
+
hydrate();
|
|
3532
|
+
const stopEffect = internalEffect(() => {
|
|
3427
3533
|
const value2 = sourceGet();
|
|
3534
|
+
if (writing) return;
|
|
3428
3535
|
try {
|
|
3429
|
-
const serialized = serialize(value2);
|
|
3536
|
+
const serialized = version !== void 0 ? serialize({ [ENVELOPE_TAG]: version, value: value2 }) : serialize(value2);
|
|
3430
3537
|
storage.setItem(key, serialized);
|
|
3431
|
-
} catch {
|
|
3538
|
+
} catch (err) {
|
|
3539
|
+
onError2?.(err, err?.name === "QuotaExceededError" ? "write" : "serialize");
|
|
3432
3540
|
}
|
|
3433
3541
|
});
|
|
3542
|
+
const enableSync = options?.syncTabs ?? (typeof window !== "undefined" && storage === globalThis.localStorage);
|
|
3543
|
+
let onStorage;
|
|
3544
|
+
if (enableSync && typeof window !== "undefined") {
|
|
3545
|
+
onStorage = (e) => {
|
|
3546
|
+
if (e.storageArea !== storage) return;
|
|
3547
|
+
if (e.key !== null && e.key !== key) return;
|
|
3548
|
+
hydrate();
|
|
3549
|
+
};
|
|
3550
|
+
window.addEventListener("storage", onStorage);
|
|
3551
|
+
}
|
|
3552
|
+
return () => {
|
|
3553
|
+
stopEffect();
|
|
3554
|
+
if (onStorage && typeof window !== "undefined") {
|
|
3555
|
+
window.removeEventListener("storage", onStorage);
|
|
3556
|
+
}
|
|
3557
|
+
};
|
|
3434
3558
|
}
|
|
3435
3559
|
|
|
3436
3560
|
// src/events/bus.ts
|