@jsonup/vue 0.0.1

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 ADDED
@@ -0,0 +1,1024 @@
1
+ import { createDocument, getChildren, isJsonDocument } from "@jsonup/core";
2
+ import { insert, move, remove, renameKey, updateValue } from "@jsonup/operation";
3
+ import { computed, createVNode, defineComponent, h, isVNode, mergeProps, onMounted, onUnmounted, ref, shallowRef, triggerRef, watch } from "vue";
4
+ import { useCssVars } from "@jsonup/themes";
5
+ //#region ../../node_modules/.pnpm/virtua@0.49.1_vue@3.5.38_typescript@6.0.3_/node_modules/virtua/lib/vue/index.js
6
+ const a = null, { min: u, max: f, abs: d, floor: p } = Math, m = (e, t, r) => u(r, f(t, e)), h$1 = (e) => [...e].sort((e, t) => e - t), _ = "function" == typeof queueMicrotask ? queueMicrotask : (e) => {
7
+ Promise.resolve().then(e);
8
+ }, b = () => {
9
+ let e;
10
+ return [new Promise((t) => {
11
+ e = t;
12
+ }), e];
13
+ }, g = (e) => {
14
+ let t;
15
+ return () => (e && (t = e(), e = void 0), t);
16
+ }, v = (e, t, r) => {
17
+ const o = r ? "unshift" : "push";
18
+ for (let r = 0; r < t; r++) e[o](-1);
19
+ return e;
20
+ }, y = (e, t) => {
21
+ const r = e.t[t];
22
+ return -1 === r ? e.o : r;
23
+ }, S = (e, t, r) => {
24
+ const o = -1 === e.t[t];
25
+ return e.t[t] = r, e.i = u(t, e.i), o;
26
+ }, z = (e, t) => {
27
+ if (!e.l) return 0;
28
+ if (e.i >= t) return e.u[t];
29
+ e.i < 0 && (e.u[0] = 0, e.i = 0);
30
+ let r = e.i, o = e.u[r];
31
+ for (; r < t;) o += y(e, r), e.u[++r] = o;
32
+ return e.i = t, o;
33
+ }, x = (e, t, r = 0, o = e.l - 1) => {
34
+ let n = r;
35
+ for (; r <= o;) {
36
+ const s = p((r + o) / 2);
37
+ z(e, s) <= t ? (n = s, r = s + 1) : o = s - 1;
38
+ }
39
+ return m(n, 0, e.l - 1);
40
+ }, $ = (e, t, r) => {
41
+ const o = t - e.l;
42
+ return e.i = r ? -1 : u(t - 1, e.i), e.l = t, o > 0 ? (v(e.u, o), v(e.t, o, r), e.o * o) : (e.u.splice(o), (r ? e.t.splice(0, -o) : e.t.splice(o)).reduce((t, r) => t - (-1 === r ? e.o : r), 0));
43
+ }, w = (e) => e.documentElement, I = (e) => e.ownerDocument, O = (e) => e.defaultView, k = /*#__PURE__*/ g(() => !!/iP(hone|od|ad)/.test(navigator.userAgent) || "MacIntel" === navigator.platform && navigator.maxTouchPoints > 0), j = /*#__PURE__*/ g(() => "scrollBehavior" in w(document).style), N = (e, t = 40, r = 0, o, n = !1) => {
44
+ let s = !!r, i = 1, l = 0, c = 0, p = 0, m = 0, _ = 0, b = 0, g = 0, w = 0, I = a, O = [0, s ? f(r - 1, 0) : -1], j = 0, N = !1;
45
+ const B = ((e, t, r) => ({
46
+ o: t,
47
+ t: r ? v(r.slice(0, u(e, r.length)), f(0, e - r.length)) : v([], e),
48
+ l: e,
49
+ i: -1,
50
+ u: v([], e + 1)
51
+ }))(e, o ? o[1] : t, o && o[0]), T = /* @__PURE__ */ new Set(), q = () => p - c, M = () => q() + _ + m, E = (e, t) => ((e, t, r, o) => {
52
+ if (o = u(o, e.l - 1), z(e, o) <= t) {
53
+ const n = x(e, r, o);
54
+ return [x(e, t, o, n), n];
55
+ }
56
+ {
57
+ const n = x(e, t, void 0, o);
58
+ return [n, x(e, r, n)];
59
+ }
60
+ })(B, e, t, O[0]), P = () => z(B, B.l), R = (e, t) => {
61
+ const r = z(B, e) - _;
62
+ return t ? P() - r - A(e) : r;
63
+ }, A = (e) => y(B, e), C = (e, t = -1) => B.t[e] === t, H = (e) => {
64
+ e && (k() && 0 !== g || I && 1 === w ? _ += e : m += e);
65
+ };
66
+ return {
67
+ p: () => {
68
+ T.clear();
69
+ },
70
+ m: () => i,
71
+ h: () => ((e) => [e.t.slice(), e.o])(B),
72
+ v: (e = 200) => {
73
+ if (!N || s) return O;
74
+ let t, r;
75
+ if (b) [t, r] = O;
76
+ else {
77
+ let o = f(0, M()), s = o + l;
78
+ n || (e = f(0, e), 1 !== g && (o -= e), 2 !== g && (s += e)), [t, r] = O = E(f(0, o), f(0, s)), I && (t = u(t, I[0]), r = f(r, I[1]));
79
+ }
80
+ return [f(t, 0), u(r, B.l - 1)];
81
+ },
82
+ S: (e) => x(B, e - c),
83
+ I: C,
84
+ O: R,
85
+ k: A,
86
+ j: () => B.l,
87
+ N: () => p,
88
+ B: () => 0 !== g,
89
+ T: () => l,
90
+ q: () => c,
91
+ M: P,
92
+ P: () => (b = m, m = 0, [b, 2 === w]),
93
+ R: (e, t) => {
94
+ const r = [e, t];
95
+ return T.add(r), () => {
96
+ T.delete(r);
97
+ };
98
+ },
99
+ A: (e, t) => {
100
+ let r, o, u = 0;
101
+ switch (e) {
102
+ case 1: {
103
+ if (t === p && 0 === w) break;
104
+ const e = b;
105
+ b = 0;
106
+ const r = t - p, n = d(r);
107
+ e && n < d(e) + 1 || 0 !== w || (g = r < 0 ? 2 : 1), s && (s = !1), p = t, u = 4;
108
+ const i = q();
109
+ i >= -l && i <= P() && (u += 1, o = n > l);
110
+ break;
111
+ }
112
+ case 2:
113
+ u = 8, 0 !== g && (r = !0, u += 1), g = 0, w = 0, I = a;
114
+ break;
115
+ case 3: {
116
+ const e = t.filter(([e, t]) => !C(e, t));
117
+ if (!e.length) break;
118
+ H(e.reduce((e, [t, r]) => {
119
+ let o;
120
+ if (2 === w) o = !0;
121
+ else if (I && 1 === w) o = t < I[0];
122
+ else {
123
+ const e = q(), r = R(t), n = A(t);
124
+ o = 1 !== g && 0 === w ? r + n < e : r < e && r + n < e + l;
125
+ }
126
+ return o && (e += r - A(t)), e;
127
+ }, 0));
128
+ for (const [t, r] of e) {
129
+ const e = A(t), o = S(B, t, r);
130
+ n && (j += o ? r : r - e);
131
+ }
132
+ n && l && j > l && (H(((e, t) => {
133
+ let r = 0;
134
+ const o = [];
135
+ e.t.forEach((e, n) => {
136
+ -1 !== e && (o.push(e), n < t && r++);
137
+ }), e.i = -1;
138
+ const n = h$1(o), s = n.length, i = s / 2 | 0, l = s % 2 == 0 ? (n[i - 1] + n[i]) / 2 : n[i], c = e.o;
139
+ return ((e.o = l) - c) * f(t - r, 0);
140
+ })(B, x(B, M()))), n = !1), u = 3, o = !0;
141
+ break;
142
+ }
143
+ case 4:
144
+ l !== t && (l || (N = o = !0), l = t, u = 3);
145
+ break;
146
+ case 5:
147
+ t[1] ? (H($(B, t[0], !0)), w = 2, u = 1) : ($(B, t[0]), u = 1);
148
+ break;
149
+ case 6:
150
+ c = t;
151
+ break;
152
+ case 7:
153
+ w = 1;
154
+ break;
155
+ case 8: I = E(t, t + l), u = 1;
156
+ }
157
+ u && (i = 1 + (2147483647 & i), r && _ && (m += _, _ = 0), T.forEach(([e, t]) => {
158
+ u & e && t(o);
159
+ }));
160
+ }
161
+ };
162
+ }, B = setTimeout, T = (e, t) => t ? -e : e, q = (e, t, r, o, n, s) => {
163
+ const i = Date.now;
164
+ let l = 0, c = !1, u = !1, f = !1, d = !1;
165
+ const p = (() => {
166
+ let t;
167
+ const r = () => {
168
+ t != a && clearTimeout(t);
169
+ }, o = () => {
170
+ r(), t = B(() => {
171
+ t = a, (() => {
172
+ if (c || u) return c = !1, void p();
173
+ f = !1, e.A(2);
174
+ })();
175
+ }, 150);
176
+ };
177
+ return o.C = r, o;
178
+ })(), m = () => {
179
+ l = i(), f && (d = !0), s && e.A(6, s()), e.A(1, o()), p();
180
+ }, h = (t) => {
181
+ if (c || !e.B() || t.ctrlKey) return;
182
+ const o = i() - l;
183
+ 150 > o && 50 < o && (r ? t.deltaX : t.deltaY) && (c = !0);
184
+ }, _ = () => {
185
+ u = !0, f = d = !1;
186
+ }, b = () => {
187
+ u = !1, k() && (f = !0);
188
+ };
189
+ return t.addEventListener("scroll", m), t.addEventListener("wheel", h, { passive: !0 }), t.addEventListener("touchstart", _, { passive: !0 }), t.addEventListener("touchend", b, { passive: !0 }), {
190
+ H: () => {
191
+ t.removeEventListener("scroll", m), t.removeEventListener("wheel", h), t.removeEventListener("touchstart", _), t.removeEventListener("touchend", b), p.C();
192
+ },
193
+ V: () => {
194
+ const [t, r] = e.P();
195
+ t && (n(t, r, d), d = !1, r && e.T() > e.M() && e.A(1, o()));
196
+ }
197
+ };
198
+ }, M = (e, t, r) => {
199
+ let o;
200
+ return [async (n, s) => {
201
+ if (!await t()) return;
202
+ o && o();
203
+ const i = () => {
204
+ const [t, r] = b();
205
+ return o = () => {
206
+ r(!1);
207
+ }, e.T() && B(o, 150), [t, e.R(2, () => {
208
+ r(!0);
209
+ })];
210
+ };
211
+ if (s && j()) e.A(8, n()), _(async () => {
212
+ for (;;) {
213
+ let t = !0;
214
+ for (let [r, o] = e.v(); r <= o; r++) if (e.I(r)) {
215
+ t = !1;
216
+ break;
217
+ }
218
+ if (t) break;
219
+ const [r, o] = i();
220
+ try {
221
+ if (!await r) return;
222
+ } finally {
223
+ o();
224
+ }
225
+ }
226
+ e.A(7), r(n(), s);
227
+ });
228
+ else for (;;) {
229
+ const [t, o] = i();
230
+ try {
231
+ if (e.A(7), r(n()), !await t) return;
232
+ } finally {
233
+ o();
234
+ }
235
+ }
236
+ }, () => {
237
+ o && o();
238
+ }];
239
+ }, E = (e) => {
240
+ let t;
241
+ return {
242
+ F(r) {
243
+ (t || (t = new (O(I(r))).ResizeObserver(e))).observe(r);
244
+ },
245
+ J(e) {
246
+ t.unobserve(e);
247
+ },
248
+ H() {
249
+ t && t.disconnect();
250
+ }
251
+ };
252
+ }, P = /*#__PURE__*/ defineComponent({
253
+ props: {
254
+ L: {
255
+ type: Object,
256
+ required: !0
257
+ },
258
+ W: {
259
+ type: Object,
260
+ required: !0
261
+ },
262
+ X: {
263
+ type: Object,
264
+ required: !0
265
+ },
266
+ Y: {
267
+ type: Function,
268
+ required: !0
269
+ },
270
+ D: {
271
+ type: Number,
272
+ required: !0
273
+ },
274
+ U: { type: Boolean },
275
+ G: { type: Boolean },
276
+ K: { type: Boolean },
277
+ Z: {
278
+ type: String,
279
+ required: !0
280
+ },
281
+ ee: Object
282
+ },
283
+ setup(e) {
284
+ const l = ref(), c = computed(() => e.L.value && e.W.O(e.D, e.K)), a = computed(() => e.L.value && e.W.I(e.D));
285
+ return watch(() => l.value && e.D, (t, r, o) => {
286
+ o(e.Y(l.value, e.D));
287
+ }, { flush: "post" }), () => {
288
+ const { X: t, U: r, G: o, Z: u } = e, f = a.value, { style: d, ...p } = e.ee ?? {}, m = {
289
+ contain: "layout style",
290
+ position: f && o ? void 0 : "absolute",
291
+ [r ? "height" : "width"]: "100%",
292
+ [r ? "top" : "left"]: "0px",
293
+ [r ? "left" : "top"]: c.value + "px",
294
+ visibility: !f || o ? void 0 : "hidden",
295
+ ...d
296
+ };
297
+ return r && (m.display = "inline-flex"), createVNode(u, mergeProps({
298
+ ref: l,
299
+ style: m
300
+ }, p), "function" == typeof (h = t) || "[object Object]" === Object.prototype.toString.call(h) && !isVNode(h) ? t : {
301
+ default: () => [t],
302
+ _: 2
303
+ }, 16, ["style"]);
304
+ var h;
305
+ };
306
+ }
307
+ }), R = (e, t) => {
308
+ if (1 === e.length) {
309
+ const t = e[0].key;
310
+ if (null != t) return t;
311
+ }
312
+ return "_" + t;
313
+ }, A = (e, t) => e[0] === t[0] && e[1] === t[1], C = /*#__PURE__*/ defineComponent({
314
+ props: {
315
+ data: {
316
+ type: Array,
317
+ required: !0
318
+ },
319
+ bufferSize: Number,
320
+ itemSize: Number,
321
+ shift: Boolean,
322
+ horizontal: Boolean,
323
+ startMargin: {
324
+ type: Number,
325
+ default: 0
326
+ },
327
+ ssrCount: Number,
328
+ scrollRef: Object,
329
+ as: {
330
+ type: String,
331
+ default: "div"
332
+ },
333
+ item: {
334
+ type: String,
335
+ default: "div"
336
+ },
337
+ itemProps: Function,
338
+ keepMounted: Array,
339
+ cache: Object
340
+ },
341
+ emits: ["scroll", "scrollEnd"],
342
+ setup(e, { emit: s, expose: u, slots: d }) {
343
+ let p = !!e.ssrCount;
344
+ const _ = e.horizontal, g = ref(), v = N(e.data.length, e.itemSize, e.ssrCount, e.cache, !e.itemSize), y = ((e, t) => {
345
+ let r;
346
+ const o = t ? "width" : "height", n = /* @__PURE__ */ new WeakMap(), s = E((t) => {
347
+ const s = [];
348
+ for (const { target: i, contentRect: l } of t) if (i.offsetParent) if (i === r) e.A(4, l[o]);
349
+ else {
350
+ const e = n.get(i);
351
+ e != a && s.push([e, l[o]]);
352
+ }
353
+ s.length && e.A(3, s);
354
+ });
355
+ return {
356
+ te(e) {
357
+ s.F(r = e);
358
+ },
359
+ re: (e, t) => (n.set(e, t), s.F(e), () => {
360
+ n.delete(e), s.J(e);
361
+ }),
362
+ p: s.H
363
+ };
364
+ })(v, _), S = ((e, t) => {
365
+ let r, o, n = b(), s = !1;
366
+ const i = t ? "scrollLeft" : "scrollTop", l = t ? "overflowX" : "overflowY", [c, a] = M(e, () => n[0], (e, o) => {
367
+ e = T(e, s), o ? r.scrollTo({
368
+ [t ? "left" : "top"]: e,
369
+ behavior: "smooth"
370
+ }) : r[i] = e;
371
+ });
372
+ return {
373
+ oe(c, u) {
374
+ r = u, t && (s = "rtl" === getComputedStyle(u).direction), o = q(e, u, t, () => T(u[i], s), (t, r, o) => {
375
+ if (o) {
376
+ const e = u.style, t = e[l];
377
+ e[l] = "hidden", B(() => {
378
+ e[l] = t;
379
+ });
380
+ }
381
+ u[i] = T(e.N() + t, s), r && a();
382
+ }), n[1](!0);
383
+ },
384
+ p() {
385
+ o && o.H(), n[1](!1), n = b();
386
+ },
387
+ ne: () => s,
388
+ se(e) {
389
+ c(() => e);
390
+ },
391
+ ie(t) {
392
+ t += e.N(), c(() => t);
393
+ },
394
+ le(t, { align: r, smooth: o, offset: n = 0 } = {}) {
395
+ if (t = m(t, 0, e.j() - 1), "nearest" === r) {
396
+ const o = e.O(t), n = e.N();
397
+ if (o < n) r = "start";
398
+ else {
399
+ if (!(o + e.k(t) > n + e.T())) return;
400
+ r = "end";
401
+ }
402
+ }
403
+ c(() => n + e.q() + e.O(t) + ("end" === r ? e.k(t) - e.T() : "center" === r ? (e.k(t) - e.T()) / 2 : 0), o);
404
+ },
405
+ ce: () => {
406
+ o && o.V();
407
+ }
408
+ };
409
+ })(v, _), z = ref(v.m());
410
+ v.R(1, () => {
411
+ z.value = v.m();
412
+ }), v.R(4, () => {
413
+ s("scroll", v.N());
414
+ }), v.R(8, () => {
415
+ s("scrollEnd");
416
+ });
417
+ const x = computed((t) => {
418
+ z.value;
419
+ const r = v.v(e.bufferSize);
420
+ return t && A(t, r) ? t : r;
421
+ }), $ = computed(() => z.value && v.B()), w = computed(() => z.value && v.M());
422
+ return onMounted(() => {
423
+ p = !1;
424
+ const t = g.value, r = requestAnimationFrame(() => {
425
+ const r = (e) => {
426
+ y.te(e), S.oe(t, e);
427
+ };
428
+ e.scrollRef ? r(e.scrollRef) : r(t.parentElement);
429
+ });
430
+ onUnmounted(() => {
431
+ cancelAnimationFrame(r);
432
+ });
433
+ }), onUnmounted(() => {
434
+ v.p(), y.p(), S.p();
435
+ }), watch(() => e.data.length, (t) => {
436
+ v.A(5, [t, e.shift]);
437
+ }), watch(() => e.startMargin, (e) => {
438
+ v.A(6, e);
439
+ }, { immediate: !0 }), watch([z], () => {
440
+ S.ce();
441
+ }, { flush: "post" }), u({
442
+ get cache() {
443
+ return v.h();
444
+ },
445
+ get scrollOffset() {
446
+ return v.N();
447
+ },
448
+ get scrollSize() {
449
+ return ((e) => f(e.M(), e.T()))(v);
450
+ },
451
+ get viewportSize() {
452
+ return v.T();
453
+ },
454
+ findItemIndex: v.S,
455
+ getItemOffset: v.O,
456
+ getItemSize: v.k,
457
+ scrollToIndex: S.le,
458
+ scrollTo: S.se,
459
+ scrollBy: S.ie
460
+ }), () => {
461
+ const t = e.as, r = e.item, o = w.value, s = S.ne(), l = [], c = (t) => {
462
+ const o = d.default({
463
+ item: e.data[t],
464
+ index: t
465
+ });
466
+ return createVNode(P, {
467
+ key: R(o, t),
468
+ L: z,
469
+ W: v,
470
+ Y: y.re,
471
+ D: t,
472
+ X: o,
473
+ U: _,
474
+ K: s,
475
+ G: p,
476
+ Z: r,
477
+ ee: e.itemProps?.({
478
+ item: e.data[t],
479
+ index: t
480
+ })
481
+ }, null, 8, [
482
+ "L",
483
+ "W",
484
+ "Y",
485
+ "D",
486
+ "X",
487
+ "U",
488
+ "K",
489
+ "G",
490
+ "Z",
491
+ "ee"
492
+ ]);
493
+ };
494
+ if (e.keepMounted) {
495
+ const t = new Set(e.keepMounted);
496
+ for (let [e, r] = x.value; e <= r; e++) t.add(e);
497
+ h$1([...t]).forEach((e) => {
498
+ l.push(c(e));
499
+ });
500
+ } else for (let [e, t] = x.value; e <= t; e++) l.push(c(e));
501
+ return createVNode(t, {
502
+ ref: g,
503
+ style: {
504
+ contain: "size style",
505
+ overflowAnchor: "none",
506
+ flex: "none",
507
+ position: "relative",
508
+ width: _ ? o + "px" : "100%",
509
+ height: _ ? "100%" : o + "px",
510
+ pointerEvents: $.value ? "none" : void 0
511
+ }
512
+ }, "function" == typeof (a = l) || "[object Object]" === Object.prototype.toString.call(a) && !isVNode(a) ? l : {
513
+ default: () => [l],
514
+ _: 2
515
+ }, 8, ["style"]);
516
+ var a;
517
+ };
518
+ }
519
+ });
520
+ //#endregion
521
+ //#region src/viewer-lines.ts
522
+ /**
523
+ * 基于可见节点创建查看器行数组
524
+ * @param document JSON 文档对象
525
+ * @param visibleNodes 可见的 JSON 节点数组
526
+ * @returns 生成的查看器行数组
527
+ */
528
+ function createViewerLines(document, visibleNodes) {
529
+ const lines = [];
530
+ const visibleIds = new Set(visibleNodes.map((node) => node.id));
531
+ const visibleByParent = /* @__PURE__ */ new Map();
532
+ for (const node of visibleNodes) {
533
+ const siblings = visibleByParent.get(node.parent) ?? [];
534
+ siblings.push(node);
535
+ visibleByParent.set(node.parent, siblings);
536
+ }
537
+ for (const node of visibleByParent.get(null) ?? []) appendNodeLines(document, visibleIds, visibleByParent, lines, node);
538
+ return lines;
539
+ }
540
+ function appendNodeLines(document, visibleIds, visibleByParent, lines, node) {
541
+ if (node.leaf) {
542
+ pushLine(lines, {
543
+ id: `${node.id}:property`,
544
+ kind: "property",
545
+ node,
546
+ depth: node.depth,
547
+ text: formatPropertyLine(node),
548
+ interactive: true
549
+ });
550
+ return;
551
+ }
552
+ if (!node.expanded) {
553
+ pushLine(lines, {
554
+ id: `${node.id}:collapsed`,
555
+ kind: "collapsed",
556
+ node,
557
+ depth: node.depth,
558
+ text: formatCollapsedLine(node),
559
+ interactive: true
560
+ });
561
+ return;
562
+ }
563
+ pushLine(lines, {
564
+ id: `${node.id}:open`,
565
+ kind: "open",
566
+ node,
567
+ depth: node.depth,
568
+ text: formatOpenLine(node),
569
+ interactive: true
570
+ });
571
+ for (const child of visibleByParent.get(node.id) ?? []) appendNodeLines(document, visibleIds, visibleByParent, lines, child);
572
+ if (shouldRenderCloseLine(document, visibleIds, node)) pushLine(lines, {
573
+ id: `${node.id}:close`,
574
+ kind: "close",
575
+ node,
576
+ depth: node.depth,
577
+ text: formatCloseLine(document, node),
578
+ interactive: false
579
+ });
580
+ }
581
+ function pushLine(lines, line) {
582
+ lines.push({
583
+ ...line,
584
+ lineNumber: lines.length + 1
585
+ });
586
+ }
587
+ function shouldRenderCloseLine(document, visibleIds, node) {
588
+ if (!node.expanded) return false;
589
+ const children = getChildren(document, node.id);
590
+ if (children.length === 0) return true;
591
+ return children.every((child) => visibleIds.has(child.id));
592
+ }
593
+ function formatOpenLine(node) {
594
+ return `${formatKey(node)}${node.type === "array" ? "[" : "{"}`;
595
+ }
596
+ function formatCloseLine(document, node) {
597
+ return `${node.type === "array" ? "]" : "}"}${hasNextSibling$1(document, node) ? "," : ""}`;
598
+ }
599
+ function formatCollapsedLine(node) {
600
+ const summary = node.type === "array" ? `${node.children} items` : `${node.children} keys`;
601
+ const brackets = node.type === "array" ? ["[", "]"] : ["{", "}"];
602
+ return `${formatKey(node)}${brackets[0]} ${summary} ${brackets[1]}`;
603
+ }
604
+ function formatPropertyLine(node) {
605
+ return `${formatKey(node)}${formatValue(node)}${hasSyntheticComma(node) ? "," : ""}`;
606
+ }
607
+ function formatKey(node) {
608
+ if (node.depth === 0 || node.key === void 0) return "";
609
+ if (node.parent && /^\d+$/.test(node.key)) return "";
610
+ return `${JSON.stringify(node.key)}: `;
611
+ }
612
+ function formatValue(node) {
613
+ if (node.value === void 0) return "";
614
+ return JSON.stringify(node.value);
615
+ }
616
+ function hasNextSibling$1(document, node) {
617
+ if (node.parent === null) return false;
618
+ const siblings = getChildren(document, node.parent);
619
+ return siblings[siblings.length - 1]?.id !== node.id;
620
+ }
621
+ function hasSyntheticComma(node) {
622
+ return node.parent !== null;
623
+ }
624
+ //#endregion
625
+ //#region src/JsonupViewer.ts
626
+ /**
627
+ * JSON 树形查看器组件
628
+ */
629
+ const JsonupViewer = defineComponent({
630
+ name: "JsonupViewer",
631
+ props: {
632
+ /** 传入的 JSON 数据或已创建的 JSON 文档对象 */
633
+ data: {
634
+ type: [
635
+ String,
636
+ Object,
637
+ Array
638
+ ],
639
+ required: true
640
+ },
641
+ /** 是否显示行号 */
642
+ lineNumbers: {
643
+ type: Boolean,
644
+ default: false
645
+ },
646
+ /** 是否开启虚拟滚动 */
647
+ virtual: {
648
+ type: Boolean,
649
+ default: false
650
+ },
651
+ /** 默认是否展开根节点 */
652
+ defaultExpandedRoot: {
653
+ type: Boolean,
654
+ default: true
655
+ },
656
+ /** 默认是否展开所有节点 */
657
+ defaultExpandedAll: {
658
+ type: Boolean,
659
+ default: false
660
+ },
661
+ /** 默认展开的深度 */
662
+ defaultExpandedDepth: {
663
+ type: [Number, Boolean],
664
+ default: void 0
665
+ },
666
+ /** 默认展开的节点路径集合 */
667
+ expandedPaths: {
668
+ type: [Array, Set],
669
+ default: void 0
670
+ },
671
+ /** 节点的身份标识树,用于保持节点状态 */
672
+ identityTree: {
673
+ type: Object,
674
+ default: void 0
675
+ },
676
+ /** 是否克隆原始数据(避免修改原对象) */
677
+ cloneRaw: {
678
+ type: Boolean,
679
+ default: false
680
+ },
681
+ /** 主题配置对象 */
682
+ theme: {
683
+ type: Object,
684
+ default: null
685
+ },
686
+ /** 是否开启单词换行 */
687
+ wordWrap: {
688
+ type: Boolean,
689
+ default: false
690
+ }
691
+ },
692
+ slots: Object,
693
+ setup(props, { slots }) {
694
+ const document = shallowRef(createViewerDocument(props.data, {
695
+ defaultExpandedRoot: props.defaultExpandedRoot,
696
+ defaultExpandedAll: props.defaultExpandedAll,
697
+ defaultExpandedDepth: props.defaultExpandedDepth,
698
+ expandedPaths: props.expandedPaths,
699
+ identityTree: props.identityTree,
700
+ cloneRaw: props.cloneRaw
701
+ }));
702
+ watch([
703
+ () => props.data,
704
+ () => props.defaultExpandedRoot,
705
+ () => props.defaultExpandedAll,
706
+ () => props.defaultExpandedDepth,
707
+ () => props.expandedPaths,
708
+ () => props.identityTree,
709
+ () => props.cloneRaw
710
+ ], ([nextData, nextDefaultExpandedRoot, nextDefaultExpandedAll, nextDefaultExpandedDepth, nextExpandedPaths, nextIdentityTree, nextCloneRaw]) => {
711
+ document.value = createViewerDocument(nextData, {
712
+ defaultExpandedRoot: nextDefaultExpandedRoot,
713
+ defaultExpandedAll: nextDefaultExpandedAll,
714
+ defaultExpandedDepth: nextDefaultExpandedDepth,
715
+ expandedPaths: nextExpandedPaths,
716
+ identityTree: nextIdentityTree,
717
+ cloneRaw: nextCloneRaw
718
+ });
719
+ }, { deep: false });
720
+ const themeVars = computed(() => useCssVars(props.theme));
721
+ const lines = computed(() => createViewerLines(document.value, document.value.visibleNodes));
722
+ const renderLine = (line) => {
723
+ const toggle = () => {
724
+ if (!line.node.expandable) return;
725
+ document.value.toggleExpanded(line.node.id);
726
+ triggerRef(document);
727
+ };
728
+ const slotProps = {
729
+ line,
730
+ text: line.text,
731
+ lineNumber: line.lineNumber,
732
+ toggle
733
+ };
734
+ const content = slots[line.kind]?.(slotProps) ?? slots.line?.(slotProps) ?? renderDefaultLine(document.value, line);
735
+ return h("div", {
736
+ "key": line.id,
737
+ "class": ["line", line.interactive ? "interactive" : void 0],
738
+ "data-state": line.kind,
739
+ "data-type": line.node.type,
740
+ "data-interactive": String(line.interactive),
741
+ "role": "treeitem",
742
+ "aria-expanded": line.node.expandable ? String(line.node.expanded) : void 0,
743
+ "style": { "--jsonup-viewer-line-depth": String(line.depth) },
744
+ "onClick": line.interactive ? toggle : void 0
745
+ }, [props.lineNumbers ? h("span", { class: [
746
+ "line-number",
747
+ "meta",
748
+ "meta-line-number"
749
+ ] }, slots.lineNumber?.(slotProps) ?? String(line.lineNumber)) : null, h("span", { class: ["content", props?.wordWrap ? "word-wrap" : void 0] }, content)]);
750
+ };
751
+ return () => h("div", {
752
+ "class": [
753
+ "jsonup-viewer",
754
+ props.lineNumbers ? "line-numbers" : void 0,
755
+ props.virtual ? "virtual" : void 0
756
+ ],
757
+ "data-theme": props.theme?.name,
758
+ "data-word-wrap": props.wordWrap ? "on" : "off",
759
+ "data-theme-type": props.theme?.type,
760
+ "role": "tree",
761
+ "style": themeVars.value
762
+ }, props.virtual ? h(C, { data: lines.value }, { default: ({ item }) => renderLine(item) }) : lines.value.map((line) => renderLine(line)));
763
+ }
764
+ });
765
+ function createViewerDocument(input, options) {
766
+ if (isJsonDocument(input)) return input;
767
+ return createDocument(input, options);
768
+ }
769
+ function renderDefaultLine(document, line) {
770
+ return createLineTokens(document, line).map((token, index) => h("span", {
771
+ key: `${line.id}:${index}:${token.text}`,
772
+ class: token.class
773
+ }, token.text));
774
+ }
775
+ function createLineTokens(document, line) {
776
+ switch (line.kind) {
777
+ case "open": return [...createKeyTokens(line.node), createBracketToken(line.node.type === "array" ? "[" : "{", getContainerType(line.node))];
778
+ case "close": return appendCommaToken([createBracketToken(line.node.type === "array" ? "]" : "}", getContainerType(line.node))], hasNextSibling(document, line.node));
779
+ case "collapsed": return [
780
+ ...createKeyTokens(line.node),
781
+ createBracketToken(line.node.type === "array" ? "[" : "{", getContainerType(line.node)),
782
+ {
783
+ text: line.node.type === "array" ? ` ${line.node.children} items ` : ` ${line.node.children} keys `,
784
+ class: [
785
+ "summary",
786
+ "meta",
787
+ "meta-summary"
788
+ ]
789
+ },
790
+ createBracketToken(line.node.type === "array" ? "]" : "}", getContainerType(line.node))
791
+ ];
792
+ case "property": return appendCommaToken([...createKeyTokens(line.node), ...createValueTokens(line.node)], hasNextSibling(document, line.node));
793
+ default: return [{
794
+ text: line.text,
795
+ class: "text"
796
+ }];
797
+ }
798
+ }
799
+ function createKeyTokens(node) {
800
+ if (node.depth === 0 || node.key === void 0) return [];
801
+ if (node.parent !== null && /^\d+$/.test(node.key)) return [];
802
+ return [
803
+ createQuoteToken("key"),
804
+ {
805
+ text: stringifyInner(node.key),
806
+ class: "key"
807
+ },
808
+ createQuoteToken("key"),
809
+ {
810
+ text: ": ",
811
+ class: ["colon", "punctuation"]
812
+ }
813
+ ];
814
+ }
815
+ function createValueTokens(node) {
816
+ switch (node.type) {
817
+ case "string": return [
818
+ createQuoteToken("string"),
819
+ {
820
+ text: stringifyInner(node.value ?? ""),
821
+ class: ["value", "string"]
822
+ },
823
+ createQuoteToken("string")
824
+ ];
825
+ case "number": return [{
826
+ text: String(node.value ?? 0),
827
+ class: ["value", "number"]
828
+ }];
829
+ case "boolean": return [{
830
+ text: String(node.value ?? false),
831
+ class: ["value", "boolean"]
832
+ }];
833
+ case "null": return [{
834
+ text: "null",
835
+ class: ["value", "null"]
836
+ }];
837
+ case "array": return [createBracketToken("[]", "array")];
838
+ case "object": return [createBracketToken("{}", "object")];
839
+ default: return [];
840
+ }
841
+ }
842
+ function appendCommaToken(tokens, hasComma) {
843
+ if (!hasComma) return tokens;
844
+ return [...tokens, {
845
+ text: ",",
846
+ class: ["comma", "punctuation"]
847
+ }];
848
+ }
849
+ function createQuoteToken(kind) {
850
+ return {
851
+ text: "\"",
852
+ class: [
853
+ "quote",
854
+ `${kind}-quote`,
855
+ "punctuation",
856
+ "quote-token",
857
+ kind
858
+ ]
859
+ };
860
+ }
861
+ function createBracketToken(text, type) {
862
+ return {
863
+ text,
864
+ class: [
865
+ "symbol",
866
+ "punctuation",
867
+ "bracket",
868
+ "storage",
869
+ type
870
+ ]
871
+ };
872
+ }
873
+ function getContainerType(node) {
874
+ return node.type === "array" ? "array" : "object";
875
+ }
876
+ function stringifyInner(value) {
877
+ return JSON.stringify(value).slice(1, -1);
878
+ }
879
+ function hasNextSibling(document, node) {
880
+ if (node.parent === null) return false;
881
+ const siblings = getChildren(document, node.parent);
882
+ return siblings[siblings.length - 1]?.id !== node.id;
883
+ }
884
+ //#endregion
885
+ //#region src/index.ts
886
+ /**
887
+ * 用于管理和操作 JSON 文档的 Vue 组合式函数
888
+ * @param input 初始 JSON 输入数据或已存在的 JSON 文档
889
+ * @param options 创建文档时的配置选项
890
+ * @returns 包含文档状态和一系列操作方法的对象
891
+ */
892
+ function useJsonDocument(input, options = {}) {
893
+ const document = shallowRef(createDocument(input, options));
894
+ const visibleNodes = computed(() => document.value.visibleNodes);
895
+ function setDocument(nextInput) {
896
+ document.value = createDocument(nextInput, options);
897
+ return document.value;
898
+ }
899
+ function refresh(nextDocument) {
900
+ document.value = isJsonDocument(nextDocument) ? nextDocument : createDocument(nextDocument, options);
901
+ return document.value;
902
+ }
903
+ function toggleExpanded(id, expanded) {
904
+ document.value.toggleExpanded(id, expanded);
905
+ triggerRef(document);
906
+ return document.value;
907
+ }
908
+ function updateValue$1(id, value) {
909
+ return refresh(updateValue(document.value, id, value));
910
+ }
911
+ function insert$1(id, inputValue) {
912
+ return refresh(insert(document.value, id, inputValue));
913
+ }
914
+ function remove$1(id) {
915
+ return refresh(remove(document.value, id));
916
+ }
917
+ function move$1(id, parentId, options) {
918
+ return refresh(move(document.value, id, parentId, options));
919
+ }
920
+ function renameKey$1(id, nextKey) {
921
+ return refresh(renameKey(document.value, id, nextKey));
922
+ }
923
+ function reset(nextInput) {
924
+ return setDocument(nextInput);
925
+ }
926
+ return {
927
+ /** 当前的 JSON 文档对象 */
928
+ document,
929
+ /** 文档中的所有节点列表 */
930
+ nodes: computed(() => document.value.nodes),
931
+ /** 当前处于可见状态的节点列表(父节点已展开的节点) */
932
+ visibleNodes,
933
+ /** 当前已展开节点的路径集合 */
934
+ expandedPaths: computed(() => new Set(document.value.state.expandedPaths)),
935
+ /**
936
+ * 设置新的文档数据
937
+ * @param nextInput 新的 JSON 输入数据或文档
938
+ * @returns 新创建的 JSON 文档对象
939
+ */
940
+ setDocument,
941
+ /**
942
+ * 重置文档数据(等同于 setDocument)
943
+ * @param nextInput 新的 JSON 输入数据或文档
944
+ * @returns 新创建的 JSON 文档对象
945
+ */
946
+ reset,
947
+ /** 文档的当前内部状态 */
948
+ state: computed(() => document.value.state),
949
+ /**
950
+ * 切换指定节点的展开/折叠状态
951
+ * @param id 节点 ID
952
+ * @param expanded 可选的强制状态,true 为展开,false 为折叠
953
+ * @returns 更新后的 JSON 文档对象
954
+ */
955
+ toggleExpanded,
956
+ /**
957
+ * 更新指定节点的值
958
+ * @param id 节点 ID
959
+ * @param value 新的节点值
960
+ * @returns 更新后的 JSON 文档对象
961
+ */
962
+ updateValue: updateValue$1,
963
+ /**
964
+ * 在指定位置插入新节点
965
+ * @param id 目标节点 ID
966
+ * @param inputValue 要插入的输入值配置
967
+ * @returns 更新后的 JSON 文档对象
968
+ */
969
+ insert: insert$1,
970
+ /**
971
+ * 移除指定节点
972
+ * @param id 节点 ID
973
+ * @returns 更新后的 JSON 文档对象
974
+ */
975
+ remove: remove$1,
976
+ /**
977
+ * 移动节点到新的父节点下
978
+ * @param id 要移动的节点 ID
979
+ * @param parentId 目标父节点 ID
980
+ * @param options 移动操作的高级选项
981
+ * @returns 更新后的 JSON 文档对象
982
+ */
983
+ move: move$1,
984
+ /**
985
+ * 重命名节点键名(仅针对对象属性)
986
+ * @param id 节点 ID
987
+ * @param nextKey 新的键名
988
+ * @returns 更新后的 JSON 文档对象
989
+ */
990
+ renameKey: renameKey$1,
991
+ /**
992
+ * 根据 ID 获取节点
993
+ * @param id 节点 ID
994
+ * @returns 匹配的节点对象,不存在时抛出错误或返回 null(取决于核心实现)
995
+ */
996
+ getNode: (id) => document.value.getNode(id),
997
+ /**
998
+ * 根据 ID 获取节点的 JSONPath 路径
999
+ * @param id 节点 ID
1000
+ * @returns 节点的路径字符串
1001
+ */
1002
+ getPath: (id) => document.value.getPath(id),
1003
+ /**
1004
+ * 根据 JSONPath 路径查找节点
1005
+ * @param path JSONPath 路径字符串
1006
+ * @returns 匹配的节点对象,不存在时返回 undefined
1007
+ */
1008
+ findByPath: (path) => document.value.findByPath(path),
1009
+ /**
1010
+ * 在文档中搜索匹配的节点
1011
+ * @param query 搜索关键字
1012
+ * @returns 匹配的节点 ID 数组
1013
+ */
1014
+ search: (query) => document.value.search(query),
1015
+ /**
1016
+ * 将当前文档状态格式化为 JSON 字符串
1017
+ * @param space 缩进的空格数,默认为 2
1018
+ * @returns 格式化后的 JSON 字符串
1019
+ */
1020
+ stringify: (space) => document.value.stringify(space)
1021
+ };
1022
+ }
1023
+ //#endregion
1024
+ export { JsonupViewer, createViewerLines, useJsonDocument };