@sylphx/lens-solid 2.3.3 → 2.3.4
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/index.js +516 -30
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -464,6 +464,229 @@ class EntityBuilder_ {
|
|
|
464
464
|
return createEntityDef(this._name, fields);
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
|
+
var valueStrategy = {
|
|
468
|
+
name: "value",
|
|
469
|
+
encode(_prev, next) {
|
|
470
|
+
return { strategy: "value", data: next };
|
|
471
|
+
},
|
|
472
|
+
decode(_current, update) {
|
|
473
|
+
return update.data;
|
|
474
|
+
},
|
|
475
|
+
estimateSize(update) {
|
|
476
|
+
return JSON.stringify(update.data).length;
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
var deltaStrategy = {
|
|
480
|
+
name: "delta",
|
|
481
|
+
encode(prev, next) {
|
|
482
|
+
const operations2 = computeStringDiff(prev, next);
|
|
483
|
+
const diffSize = JSON.stringify(operations2).length;
|
|
484
|
+
const valueSize = next.length + 20;
|
|
485
|
+
if (diffSize >= valueSize) {
|
|
486
|
+
return { strategy: "value", data: next };
|
|
487
|
+
}
|
|
488
|
+
return { strategy: "delta", data: operations2 };
|
|
489
|
+
},
|
|
490
|
+
decode(current, update) {
|
|
491
|
+
if (update.strategy === "value") {
|
|
492
|
+
return update.data;
|
|
493
|
+
}
|
|
494
|
+
const operations2 = update.data;
|
|
495
|
+
return applyStringDiff(current, operations2);
|
|
496
|
+
},
|
|
497
|
+
estimateSize(update) {
|
|
498
|
+
return JSON.stringify(update.data).length;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
function computeStringDiff(prev, next) {
|
|
502
|
+
const operations2 = [];
|
|
503
|
+
let prefixLen = 0;
|
|
504
|
+
const minLen = Math.min(prev.length, next.length);
|
|
505
|
+
while (prefixLen < minLen && prev[prefixLen] === next[prefixLen]) {
|
|
506
|
+
prefixLen++;
|
|
507
|
+
}
|
|
508
|
+
let suffixLen = 0;
|
|
509
|
+
const remainingPrev = prev.length - prefixLen;
|
|
510
|
+
const remainingNext = next.length - prefixLen;
|
|
511
|
+
const maxSuffix = Math.min(remainingPrev, remainingNext);
|
|
512
|
+
while (suffixLen < maxSuffix && prev[prev.length - 1 - suffixLen] === next[next.length - 1 - suffixLen]) {
|
|
513
|
+
suffixLen++;
|
|
514
|
+
}
|
|
515
|
+
const deleteCount = prev.length - prefixLen - suffixLen;
|
|
516
|
+
const insertText = next.slice(prefixLen, next.length - suffixLen || undefined);
|
|
517
|
+
if (deleteCount > 0 || insertText.length > 0) {
|
|
518
|
+
operations2.push({
|
|
519
|
+
position: prefixLen,
|
|
520
|
+
...deleteCount > 0 ? { delete: deleteCount } : {},
|
|
521
|
+
...insertText.length > 0 ? { insert: insertText } : {}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return operations2;
|
|
525
|
+
}
|
|
526
|
+
function applyStringDiff(current, operations2) {
|
|
527
|
+
let result = current;
|
|
528
|
+
const sortedOps = [...operations2].sort((a, b) => b.position - a.position);
|
|
529
|
+
for (const op2 of sortedOps) {
|
|
530
|
+
const before = result.slice(0, op2.position);
|
|
531
|
+
const after = result.slice(op2.position + (op2.delete ?? 0));
|
|
532
|
+
result = before + (op2.insert ?? "") + after;
|
|
533
|
+
}
|
|
534
|
+
return result;
|
|
535
|
+
}
|
|
536
|
+
var patchStrategy = {
|
|
537
|
+
name: "patch",
|
|
538
|
+
encode(prev, next) {
|
|
539
|
+
const operations2 = computeJsonPatch(prev, next);
|
|
540
|
+
const patchSize = JSON.stringify(operations2).length;
|
|
541
|
+
const valueSize = JSON.stringify(next).length + 20;
|
|
542
|
+
if (patchSize >= valueSize) {
|
|
543
|
+
return { strategy: "value", data: next };
|
|
544
|
+
}
|
|
545
|
+
return { strategy: "patch", data: operations2 };
|
|
546
|
+
},
|
|
547
|
+
decode(current, update) {
|
|
548
|
+
if (update.strategy === "value") {
|
|
549
|
+
return update.data;
|
|
550
|
+
}
|
|
551
|
+
const operations2 = update.data;
|
|
552
|
+
return applyJsonPatch(current, operations2);
|
|
553
|
+
},
|
|
554
|
+
estimateSize(update) {
|
|
555
|
+
return JSON.stringify(update.data).length;
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
function computeJsonPatch(prev, next, basePath = "") {
|
|
559
|
+
const operations2 = [];
|
|
560
|
+
const prevObj = prev;
|
|
561
|
+
const nextObj = next;
|
|
562
|
+
for (const key of Object.keys(prevObj)) {
|
|
563
|
+
if (!(key in nextObj)) {
|
|
564
|
+
operations2.push({ op: "remove", path: `${basePath}/${escapeJsonPointer(key)}` });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
for (const [key, nextValue] of Object.entries(nextObj)) {
|
|
568
|
+
const path = `${basePath}/${escapeJsonPointer(key)}`;
|
|
569
|
+
const prevValue = prevObj[key];
|
|
570
|
+
if (!(key in prevObj)) {
|
|
571
|
+
operations2.push({ op: "add", path, value: nextValue });
|
|
572
|
+
} else if (!deepEqual2(prevValue, nextValue)) {
|
|
573
|
+
if (isPlainObject(prevValue) && isPlainObject(nextValue) && !Array.isArray(prevValue) && !Array.isArray(nextValue)) {
|
|
574
|
+
operations2.push(...computeJsonPatch(prevValue, nextValue, path));
|
|
575
|
+
} else {
|
|
576
|
+
operations2.push({ op: "replace", path, value: nextValue });
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return operations2;
|
|
581
|
+
}
|
|
582
|
+
function applyJsonPatch(current, operations2) {
|
|
583
|
+
const result = structuredClone(current);
|
|
584
|
+
for (const op2 of operations2) {
|
|
585
|
+
const pathParts = parseJsonPointer(op2.path);
|
|
586
|
+
switch (op2.op) {
|
|
587
|
+
case "add":
|
|
588
|
+
case "replace":
|
|
589
|
+
setValueAtPath(result, pathParts, op2.value);
|
|
590
|
+
break;
|
|
591
|
+
case "remove":
|
|
592
|
+
removeValueAtPath(result, pathParts);
|
|
593
|
+
break;
|
|
594
|
+
case "move":
|
|
595
|
+
if (op2.from) {
|
|
596
|
+
const fromParts = parseJsonPointer(op2.from);
|
|
597
|
+
const value = getValueAtPath(result, fromParts);
|
|
598
|
+
removeValueAtPath(result, fromParts);
|
|
599
|
+
setValueAtPath(result, pathParts, value);
|
|
600
|
+
}
|
|
601
|
+
break;
|
|
602
|
+
case "copy":
|
|
603
|
+
if (op2.from) {
|
|
604
|
+
const fromParts = parseJsonPointer(op2.from);
|
|
605
|
+
const value = structuredClone(getValueAtPath(result, fromParts));
|
|
606
|
+
setValueAtPath(result, pathParts, value);
|
|
607
|
+
}
|
|
608
|
+
break;
|
|
609
|
+
case "test":
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
return result;
|
|
614
|
+
}
|
|
615
|
+
function applyUpdate(current, update) {
|
|
616
|
+
switch (update.strategy) {
|
|
617
|
+
case "value":
|
|
618
|
+
return valueStrategy.decode(current, update);
|
|
619
|
+
case "delta":
|
|
620
|
+
return deltaStrategy.decode(current, update);
|
|
621
|
+
case "patch":
|
|
622
|
+
return patchStrategy.decode(current, update);
|
|
623
|
+
default:
|
|
624
|
+
return update.data;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
function isPlainObject(value) {
|
|
628
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
629
|
+
}
|
|
630
|
+
function deepEqual2(a, b) {
|
|
631
|
+
if (a === b)
|
|
632
|
+
return true;
|
|
633
|
+
if (typeof a !== typeof b)
|
|
634
|
+
return false;
|
|
635
|
+
if (typeof a !== "object" || a === null || b === null)
|
|
636
|
+
return false;
|
|
637
|
+
const aKeys = Object.keys(a);
|
|
638
|
+
const bKeys = Object.keys(b);
|
|
639
|
+
if (aKeys.length !== bKeys.length)
|
|
640
|
+
return false;
|
|
641
|
+
for (const key of aKeys) {
|
|
642
|
+
if (!deepEqual2(a[key], b[key])) {
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
function escapeJsonPointer(str) {
|
|
649
|
+
return str.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
650
|
+
}
|
|
651
|
+
function parseJsonPointer(path) {
|
|
652
|
+
if (!path || path === "/")
|
|
653
|
+
return [];
|
|
654
|
+
return path.slice(1).split("/").map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
|
|
655
|
+
}
|
|
656
|
+
function getValueAtPath(obj, path) {
|
|
657
|
+
let current = obj;
|
|
658
|
+
for (const key of path) {
|
|
659
|
+
if (current === null || typeof current !== "object")
|
|
660
|
+
return;
|
|
661
|
+
current = current[key];
|
|
662
|
+
}
|
|
663
|
+
return current;
|
|
664
|
+
}
|
|
665
|
+
function setValueAtPath(obj, path, value) {
|
|
666
|
+
if (path.length === 0)
|
|
667
|
+
return;
|
|
668
|
+
let current = obj;
|
|
669
|
+
for (let i = 0;i < path.length - 1; i++) {
|
|
670
|
+
const key = path[i];
|
|
671
|
+
if (!(key in current) || typeof current[key] !== "object") {
|
|
672
|
+
current[key] = {};
|
|
673
|
+
}
|
|
674
|
+
current = current[key];
|
|
675
|
+
}
|
|
676
|
+
current[path[path.length - 1]] = value;
|
|
677
|
+
}
|
|
678
|
+
function removeValueAtPath(obj, path) {
|
|
679
|
+
if (path.length === 0)
|
|
680
|
+
return;
|
|
681
|
+
let current = obj;
|
|
682
|
+
for (let i = 0;i < path.length - 1; i++) {
|
|
683
|
+
const key = path[i];
|
|
684
|
+
if (!(key in current) || typeof current[key] !== "object")
|
|
685
|
+
return;
|
|
686
|
+
current = current[key];
|
|
687
|
+
}
|
|
688
|
+
delete current[path[path.length - 1]];
|
|
689
|
+
}
|
|
467
690
|
var OPTIMISTIC_PLUGIN_SYMBOL = Symbol.for("lens:optimistic-plugin");
|
|
468
691
|
var DEFAULT_OPERATION_LOG_CONFIG = {
|
|
469
692
|
maxEntries: 1e4,
|
|
@@ -846,6 +1069,245 @@ class ReconnectionMetricsTracker {
|
|
|
846
1069
|
return sorted[Math.max(0, index)];
|
|
847
1070
|
}
|
|
848
1071
|
}
|
|
1072
|
+
function applyOps(state, ops) {
|
|
1073
|
+
let result = state;
|
|
1074
|
+
for (const op2 of ops) {
|
|
1075
|
+
result = applyOp(result, op2);
|
|
1076
|
+
}
|
|
1077
|
+
return result;
|
|
1078
|
+
}
|
|
1079
|
+
function applyOp(state, op2) {
|
|
1080
|
+
switch (op2.o) {
|
|
1081
|
+
case "set":
|
|
1082
|
+
return setAtPath(state, op2.p, op2.v);
|
|
1083
|
+
case "del":
|
|
1084
|
+
return deleteAtPath(state, op2.p);
|
|
1085
|
+
case "merge":
|
|
1086
|
+
return mergeAtPath(state, op2.p, op2.v);
|
|
1087
|
+
case "delta": {
|
|
1088
|
+
const current = getAtPath(state, op2.p);
|
|
1089
|
+
const updated = applyUpdate(current, { strategy: "delta", data: op2.d });
|
|
1090
|
+
return setAtPath(state, op2.p, updated);
|
|
1091
|
+
}
|
|
1092
|
+
case "patch": {
|
|
1093
|
+
const current = getAtPath(state, op2.p);
|
|
1094
|
+
const updated = applyUpdate(current, { strategy: "patch", data: op2.d });
|
|
1095
|
+
return setAtPath(state, op2.p, updated);
|
|
1096
|
+
}
|
|
1097
|
+
case "push":
|
|
1098
|
+
return arrayPush(state, op2.p, op2.v);
|
|
1099
|
+
case "unshift":
|
|
1100
|
+
return arrayUnshift(state, op2.p, op2.v);
|
|
1101
|
+
case "splice":
|
|
1102
|
+
return arraySplice(state, op2.p, op2.i, op2.dc, op2.v);
|
|
1103
|
+
case "arrSet":
|
|
1104
|
+
return arraySetAt(state, op2.p, op2.i, op2.v);
|
|
1105
|
+
case "arrDel":
|
|
1106
|
+
return arrayDeleteAt(state, op2.p, op2.i);
|
|
1107
|
+
case "arrSetId":
|
|
1108
|
+
return arraySetById(state, op2.p, op2.id, op2.v);
|
|
1109
|
+
case "arrDelId":
|
|
1110
|
+
return arrayDeleteById(state, op2.p, op2.id);
|
|
1111
|
+
case "arrMerge":
|
|
1112
|
+
return arrayMergeAt(state, op2.p, op2.i, op2.v);
|
|
1113
|
+
case "arrMergeId":
|
|
1114
|
+
return arrayMergeById(state, op2.p, op2.id, op2.v);
|
|
1115
|
+
default:
|
|
1116
|
+
return state;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
function parsePath(path) {
|
|
1120
|
+
if (!path)
|
|
1121
|
+
return [];
|
|
1122
|
+
return path.split(".");
|
|
1123
|
+
}
|
|
1124
|
+
function getAtPath(state, path) {
|
|
1125
|
+
const segments = parsePath(path);
|
|
1126
|
+
let current = state;
|
|
1127
|
+
for (const segment of segments) {
|
|
1128
|
+
if (current === null || current === undefined)
|
|
1129
|
+
return;
|
|
1130
|
+
if (typeof current !== "object")
|
|
1131
|
+
return;
|
|
1132
|
+
current = current[segment];
|
|
1133
|
+
}
|
|
1134
|
+
return current;
|
|
1135
|
+
}
|
|
1136
|
+
function setAtPath(state, path, value) {
|
|
1137
|
+
const segments = parsePath(path);
|
|
1138
|
+
if (segments.length === 0)
|
|
1139
|
+
return value;
|
|
1140
|
+
return updateAtPath(state, segments, () => value);
|
|
1141
|
+
}
|
|
1142
|
+
function deleteAtPath(state, path) {
|
|
1143
|
+
const segments = parsePath(path);
|
|
1144
|
+
if (segments.length === 0)
|
|
1145
|
+
return;
|
|
1146
|
+
const parentPath = segments.slice(0, -1);
|
|
1147
|
+
const key = segments[segments.length - 1];
|
|
1148
|
+
return updateAtPath(state, parentPath, (parent) => {
|
|
1149
|
+
if (parent === null || parent === undefined)
|
|
1150
|
+
return parent;
|
|
1151
|
+
if (Array.isArray(parent)) {
|
|
1152
|
+
const idx = parseInt(key, 10);
|
|
1153
|
+
const result = [...parent];
|
|
1154
|
+
result.splice(idx, 1);
|
|
1155
|
+
return result;
|
|
1156
|
+
}
|
|
1157
|
+
if (typeof parent === "object") {
|
|
1158
|
+
const { [key]: _, ...rest } = parent;
|
|
1159
|
+
return rest;
|
|
1160
|
+
}
|
|
1161
|
+
return parent;
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
function mergeAtPath(state, path, value) {
|
|
1165
|
+
const segments = parsePath(path);
|
|
1166
|
+
return updateAtPath(state, segments, (current) => {
|
|
1167
|
+
if (current === null || current === undefined)
|
|
1168
|
+
return value;
|
|
1169
|
+
if (typeof current !== "object" || Array.isArray(current))
|
|
1170
|
+
return value;
|
|
1171
|
+
return { ...current, ...value };
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
function updateAtPath(state, segments, transform) {
|
|
1175
|
+
if (segments.length === 0) {
|
|
1176
|
+
return transform(state);
|
|
1177
|
+
}
|
|
1178
|
+
const [head, ...tail] = segments;
|
|
1179
|
+
if (state === null || state === undefined) {
|
|
1180
|
+
const isArrayIndex = /^\d+$/.test(head);
|
|
1181
|
+
const newState = isArrayIndex ? [] : {};
|
|
1182
|
+
return updateAtPath(newState, segments, transform);
|
|
1183
|
+
}
|
|
1184
|
+
if (Array.isArray(state)) {
|
|
1185
|
+
const result = [...state];
|
|
1186
|
+
const idx = parseInt(head, 10);
|
|
1187
|
+
result[idx] = updateAtPath(result[idx], tail, transform);
|
|
1188
|
+
return result;
|
|
1189
|
+
}
|
|
1190
|
+
if (typeof state === "object") {
|
|
1191
|
+
const obj = state;
|
|
1192
|
+
return {
|
|
1193
|
+
...obj,
|
|
1194
|
+
[head]: updateAtPath(obj[head], tail, transform)
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
return { [head]: updateAtPath(undefined, tail, transform) };
|
|
1198
|
+
}
|
|
1199
|
+
function arrayPush(state, path, items) {
|
|
1200
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1201
|
+
if (!Array.isArray(arr))
|
|
1202
|
+
return items;
|
|
1203
|
+
return [...arr, ...items];
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
function arrayUnshift(state, path, items) {
|
|
1207
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1208
|
+
if (!Array.isArray(arr))
|
|
1209
|
+
return items;
|
|
1210
|
+
return [...items, ...arr];
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
function arraySplice(state, path, index, deleteCount, items) {
|
|
1214
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1215
|
+
if (!Array.isArray(arr))
|
|
1216
|
+
return items ?? [];
|
|
1217
|
+
const result = [...arr];
|
|
1218
|
+
if (items) {
|
|
1219
|
+
result.splice(index, deleteCount, ...items);
|
|
1220
|
+
} else {
|
|
1221
|
+
result.splice(index, deleteCount);
|
|
1222
|
+
}
|
|
1223
|
+
return result;
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
function arraySetAt(state, path, index, value) {
|
|
1227
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1228
|
+
if (!Array.isArray(arr)) {
|
|
1229
|
+
const result2 = [];
|
|
1230
|
+
result2[index] = value;
|
|
1231
|
+
return result2;
|
|
1232
|
+
}
|
|
1233
|
+
const result = [...arr];
|
|
1234
|
+
result[index] = value;
|
|
1235
|
+
return result;
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
function arrayDeleteAt(state, path, index) {
|
|
1239
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1240
|
+
if (!Array.isArray(arr))
|
|
1241
|
+
return [];
|
|
1242
|
+
const result = [...arr];
|
|
1243
|
+
result.splice(index, 1);
|
|
1244
|
+
return result;
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
function arraySetById(state, path, id2, value) {
|
|
1248
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1249
|
+
if (!Array.isArray(arr))
|
|
1250
|
+
return [value];
|
|
1251
|
+
const index = arr.findIndex((item) => item && typeof item === "object" && item.id === id2);
|
|
1252
|
+
if (index === -1) {
|
|
1253
|
+
return [...arr, value];
|
|
1254
|
+
}
|
|
1255
|
+
const result = [...arr];
|
|
1256
|
+
result[index] = value;
|
|
1257
|
+
return result;
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
function arrayDeleteById(state, path, id2) {
|
|
1261
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1262
|
+
if (!Array.isArray(arr))
|
|
1263
|
+
return [];
|
|
1264
|
+
return arr.filter((item) => !(item && typeof item === "object" && item.id === id2));
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
function arrayMergeAt(state, path, index, value) {
|
|
1268
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1269
|
+
if (!Array.isArray(arr)) {
|
|
1270
|
+
const result2 = [];
|
|
1271
|
+
result2[index] = value;
|
|
1272
|
+
return result2;
|
|
1273
|
+
}
|
|
1274
|
+
const result = [...arr];
|
|
1275
|
+
const current = result[index];
|
|
1276
|
+
if (current && typeof current === "object" && !Array.isArray(current)) {
|
|
1277
|
+
result[index] = { ...current, ...value };
|
|
1278
|
+
} else {
|
|
1279
|
+
result[index] = value;
|
|
1280
|
+
}
|
|
1281
|
+
return result;
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
function arrayMergeById(state, path, id2, value) {
|
|
1285
|
+
return updateAtPath(state, parsePath(path), (arr) => {
|
|
1286
|
+
if (!Array.isArray(arr))
|
|
1287
|
+
return [{ id: id2, ...value }];
|
|
1288
|
+
const index = arr.findIndex((item) => item && typeof item === "object" && item.id === id2);
|
|
1289
|
+
if (index === -1) {
|
|
1290
|
+
return [...arr, { id: id2, ...value }];
|
|
1291
|
+
}
|
|
1292
|
+
const result = [...arr];
|
|
1293
|
+
const current = result[index];
|
|
1294
|
+
if (current && typeof current === "object" && !Array.isArray(current)) {
|
|
1295
|
+
result[index] = { ...current, ...value };
|
|
1296
|
+
} else {
|
|
1297
|
+
result[index] = { id: id2, ...value };
|
|
1298
|
+
}
|
|
1299
|
+
return result;
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
function isSnapshot(msg) {
|
|
1303
|
+
return msg.$ === "snapshot";
|
|
1304
|
+
}
|
|
1305
|
+
function isOps(msg) {
|
|
1306
|
+
return msg.$ === "ops";
|
|
1307
|
+
}
|
|
1308
|
+
function isError(msg) {
|
|
1309
|
+
return msg.$ === "error";
|
|
1310
|
+
}
|
|
849
1311
|
|
|
850
1312
|
// ../client/dist/index.js
|
|
851
1313
|
function hasAnySubscription(entities, entityName, select, visited = new Set) {
|
|
@@ -926,16 +1388,16 @@ class ClientImpl {
|
|
|
926
1388
|
result = await plugin.afterResponse(result, processedOp);
|
|
927
1389
|
}
|
|
928
1390
|
}
|
|
929
|
-
if (result
|
|
930
|
-
const error = result.error;
|
|
1391
|
+
if (isError(result)) {
|
|
1392
|
+
const error = new Error(result.error);
|
|
931
1393
|
for (const plugin of this.plugins) {
|
|
932
1394
|
if (plugin.onError) {
|
|
933
1395
|
try {
|
|
934
1396
|
result = await plugin.onError(error, processedOp, () => this.execute(processedOp));
|
|
935
|
-
if (!result
|
|
1397
|
+
if (!isError(result))
|
|
936
1398
|
break;
|
|
937
1399
|
} catch (e) {
|
|
938
|
-
result = { error: e };
|
|
1400
|
+
result = { $: "error", error: e instanceof Error ? e.message : String(e) };
|
|
939
1401
|
}
|
|
940
1402
|
}
|
|
941
1403
|
}
|
|
@@ -1094,14 +1556,17 @@ class ClientImpl {
|
|
|
1094
1556
|
meta: select ? { select } : {}
|
|
1095
1557
|
};
|
|
1096
1558
|
const response = await this.execute(op2);
|
|
1097
|
-
if (response
|
|
1098
|
-
throw response.error;
|
|
1559
|
+
if (isError(response)) {
|
|
1560
|
+
throw new Error(response.error);
|
|
1099
1561
|
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
observer.
|
|
1562
|
+
if (isSnapshot(response)) {
|
|
1563
|
+
sub.data = response.data;
|
|
1564
|
+
for (const observer of sub.observers) {
|
|
1565
|
+
observer.next?.(response.data);
|
|
1566
|
+
}
|
|
1567
|
+
return onfulfilled ? onfulfilled(response.data) : response.data;
|
|
1103
1568
|
}
|
|
1104
|
-
return onfulfilled ? onfulfilled(
|
|
1569
|
+
return onfulfilled ? onfulfilled(sub.data) : sub.data;
|
|
1105
1570
|
} catch (error) {
|
|
1106
1571
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
1107
1572
|
sub.error = err;
|
|
@@ -1136,16 +1601,29 @@ class ClientImpl {
|
|
|
1136
1601
|
const resultOrObservable = this.transport.execute(op2);
|
|
1137
1602
|
if (this.isObservable(resultOrObservable)) {
|
|
1138
1603
|
const subscription = resultOrObservable.subscribe({
|
|
1139
|
-
next: (
|
|
1140
|
-
if (
|
|
1141
|
-
sub.data =
|
|
1604
|
+
next: (message) => {
|
|
1605
|
+
if (isSnapshot(message)) {
|
|
1606
|
+
sub.data = message.data;
|
|
1142
1607
|
sub.error = null;
|
|
1143
1608
|
for (const observer of sub.observers) {
|
|
1144
|
-
observer.next?.(
|
|
1609
|
+
observer.next?.(message.data);
|
|
1145
1610
|
}
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1611
|
+
} else if (isOps(message)) {
|
|
1612
|
+
try {
|
|
1613
|
+
sub.data = applyOps(sub.data, message.ops);
|
|
1614
|
+
sub.error = null;
|
|
1615
|
+
for (const observer of sub.observers) {
|
|
1616
|
+
observer.next?.(sub.data);
|
|
1617
|
+
}
|
|
1618
|
+
} catch (updateErr) {
|
|
1619
|
+
const err = updateErr instanceof Error ? updateErr : new Error(String(updateErr));
|
|
1620
|
+
sub.error = err;
|
|
1621
|
+
for (const observer of sub.observers) {
|
|
1622
|
+
observer.error?.(err);
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
} else if (isError(message)) {
|
|
1626
|
+
const err = new Error(message.error);
|
|
1149
1627
|
sub.error = err;
|
|
1150
1628
|
for (const observer of sub.observers) {
|
|
1151
1629
|
observer.error?.(err);
|
|
@@ -1186,10 +1664,13 @@ class ClientImpl {
|
|
|
1186
1664
|
meta: select ? { select } : {}
|
|
1187
1665
|
};
|
|
1188
1666
|
const response = await this.execute(op2);
|
|
1189
|
-
if (response
|
|
1190
|
-
throw response.error;
|
|
1667
|
+
if (isError(response)) {
|
|
1668
|
+
throw new Error(response.error);
|
|
1669
|
+
}
|
|
1670
|
+
if (isSnapshot(response)) {
|
|
1671
|
+
return { data: response.data };
|
|
1191
1672
|
}
|
|
1192
|
-
return { data:
|
|
1673
|
+
return { data: null };
|
|
1193
1674
|
}
|
|
1194
1675
|
createAccessor(path) {
|
|
1195
1676
|
return (descriptor) => {
|
|
@@ -1309,16 +1790,17 @@ async function executeRequest(baseUrl, op2, options) {
|
|
|
1309
1790
|
}
|
|
1310
1791
|
if (!response.ok) {
|
|
1311
1792
|
return {
|
|
1312
|
-
error
|
|
1793
|
+
$: "error",
|
|
1794
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
1313
1795
|
};
|
|
1314
1796
|
}
|
|
1315
1797
|
const result = await response.json();
|
|
1316
1798
|
return result;
|
|
1317
1799
|
} catch (error) {
|
|
1318
1800
|
if (error instanceof Error && error.name === "AbortError") {
|
|
1319
|
-
return { error:
|
|
1801
|
+
return { $: "error", error: "Request timeout" };
|
|
1320
1802
|
}
|
|
1321
|
-
return { error };
|
|
1803
|
+
return { $: "error", error: error instanceof Error ? error.message : String(error) };
|
|
1322
1804
|
}
|
|
1323
1805
|
}
|
|
1324
1806
|
function createPollingObservable(baseUrl, op2, options) {
|
|
@@ -1331,24 +1813,28 @@ function createPollingObservable(baseUrl, op2, options) {
|
|
|
1331
1813
|
if (!active)
|
|
1332
1814
|
return;
|
|
1333
1815
|
try {
|
|
1334
|
-
const
|
|
1816
|
+
const message = await executeRequest(baseUrl, op2, {
|
|
1335
1817
|
headers: options.headers,
|
|
1336
1818
|
fetch: options.fetch
|
|
1337
1819
|
});
|
|
1338
1820
|
if (!active)
|
|
1339
1821
|
return;
|
|
1340
|
-
if (
|
|
1822
|
+
if (isError(message)) {
|
|
1341
1823
|
retries++;
|
|
1342
1824
|
if (retries > options.maxRetries) {
|
|
1343
|
-
observer.error?.(
|
|
1825
|
+
observer.error?.(new Error(message.error));
|
|
1344
1826
|
return;
|
|
1345
1827
|
}
|
|
1346
1828
|
} else {
|
|
1347
1829
|
retries = 0;
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1830
|
+
if (isSnapshot(message)) {
|
|
1831
|
+
const hasDataChange = JSON.stringify(message.data) !== JSON.stringify(lastValue);
|
|
1832
|
+
if (hasDataChange) {
|
|
1833
|
+
lastValue = message.data;
|
|
1834
|
+
observer.next?.(message);
|
|
1835
|
+
}
|
|
1836
|
+
} else if (isOps(message)) {
|
|
1837
|
+
observer.next?.(message);
|
|
1352
1838
|
}
|
|
1353
1839
|
}
|
|
1354
1840
|
if (active) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylphx/lens-solid",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.4",
|
|
4
4
|
"description": "SolidJS bindings for Lens API framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"author": "SylphxAI",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@sylphx/lens-client": "^2.
|
|
35
|
-
"@sylphx/lens-core": "^2.
|
|
34
|
+
"@sylphx/lens-client": "^2.6.0",
|
|
35
|
+
"@sylphx/lens-core": "^2.12.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"solid-js": ">=1.8.0"
|