usage-board 3.0.0 → 3.1.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.mjs +1 -1
- package/dist/public/_nuxt/{y3weNNd-.js → B6C9KBQ4.js} +2 -2
- package/dist/public/_nuxt/Bv6agYS5.js +119 -0
- package/dist/public/_nuxt/BvRyOET7.js +1 -0
- package/dist/public/_nuxt/CMWftE4h.js +1 -0
- package/dist/public/_nuxt/{Be3rizqy.js → COIbUy5w.js} +1 -1
- package/dist/public/_nuxt/CXLmM1yO.js +25 -0
- package/dist/public/_nuxt/DFqWEFN4.js +1 -0
- package/dist/public/_nuxt/DUoLvn3A.js +6 -0
- package/dist/public/_nuxt/D_W11Quh.js +21 -0
- package/dist/public/_nuxt/DgKrPjze.js +4 -0
- package/dist/public/_nuxt/DkxY2YMp.js +1 -0
- package/dist/public/_nuxt/{7Dy4NLP8.js → DtbPvE6R.js} +24 -24
- package/dist/public/_nuxt/HiqUua3-.js +1 -0
- package/dist/public/_nuxt/builds/latest.json +1 -1
- package/dist/public/_nuxt/builds/meta/6f98f1cb-266c-475e-a249-dad346a55f24.json +1 -0
- package/dist/public/_nuxt/entry.vHfFzkyD.css +1 -0
- package/dist/public/_nuxt/error-404.CFBEg71j.css +1 -0
- package/dist/public/_nuxt/error-500.BqCnH31G.css +1 -0
- package/dist/public/_nuxt/uHQwCIHg.js +1 -0
- package/dist/server/chunks/_/error-500.mjs +2 -20
- package/dist/server/chunks/build/client.precomputed.mjs +1 -1
- package/dist/server/chunks/nitro/nitro.mjs +2303 -3614
- package/dist/server/chunks/routes/api/analysis/agent/session.json.mjs +21 -0
- package/dist/server/chunks/routes/api/analysis/agent/token.json.mjs +24 -0
- package/dist/server/chunks/routes/api/analysis/cache.json.mjs +24 -0
- package/dist/server/chunks/routes/api/analysis/hot-project.json.mjs +24 -0
- package/dist/server/chunks/routes/api/analysis/model.json.mjs +24 -0
- package/dist/server/chunks/routes/api/analysis/overview-cards.json.mjs +24 -0
- package/dist/server/chunks/routes/api/analysis/session.json.mjs +21 -0
- package/dist/server/chunks/routes/api/analysis/token/daily.json.mjs +21 -0
- package/dist/server/chunks/routes/api/analysis/token.json.mjs +24 -0
- package/dist/server/chunks/routes/api/payload.json.mjs +9 -10
- package/dist/server/chunks/routes/api/projects/_project/modules.get.mjs +9 -10
- package/dist/server/chunks/routes/api/projects/catalog.get.mjs +9 -10
- package/dist/server/chunks/routes/renderer.mjs +17 -39183
- package/dist/server/chunks/routes/ws.mjs +9 -10
- package/dist/server/index.mjs +9 -10
- package/dist/server/node_modules/@babel/parser/lib/index.js +14582 -0
- package/dist/server/node_modules/@babel/parser/package.json +50 -0
- package/dist/server/node_modules/@iconify/utils/lib/colors/index.js +292 -0
- package/dist/server/node_modules/@iconify/utils/lib/colors/keywords.js +702 -0
- package/dist/server/node_modules/@iconify/utils/lib/css/common.js +76 -0
- package/dist/server/node_modules/@iconify/utils/lib/css/format.js +40 -0
- package/dist/server/node_modules/@iconify/utils/lib/css/icon.js +52 -0
- package/dist/server/node_modules/@iconify/utils/lib/css/icons.js +133 -0
- package/dist/server/node_modules/@iconify/utils/lib/customisations/bool.js +20 -0
- package/dist/server/node_modules/@iconify/utils/lib/customisations/defaults.js +15 -0
- package/dist/server/node_modules/@iconify/utils/lib/customisations/flip.js +18 -0
- package/dist/server/node_modules/@iconify/utils/lib/customisations/merge.js +18 -0
- package/dist/server/node_modules/@iconify/utils/lib/customisations/rotate.js +31 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/cleanup.js +80 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/convert.js +102 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/data.js +29 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/format.js +60 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/parse.js +50 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/regex/base.js +204 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/regex/create.js +35 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/regex/numbers.js +134 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/regex/similar.js +167 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/regex/tree.js +81 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/replace/find.js +94 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/replace/replace.js +28 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/components.js +78 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/missing.js +68 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/name.js +47 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/parse.js +105 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/similar.js +38 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/tree.js +94 -0
- package/dist/server/node_modules/@iconify/utils/lib/emoji/test/variations.js +64 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon/defaults.js +26 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon/merge.js +18 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon/name.js +58 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon/square.js +34 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon/transformations.js +13 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/convert-info.js +126 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/expand.js +21 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/get-icon.js +27 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/get-icons.js +38 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/minify.js +93 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/parse.js +48 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/tree.js +24 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/validate-basic.js +44 -0
- package/dist/server/node_modules/@iconify/utils/lib/icon-set/validate.js +125 -0
- package/dist/server/node_modules/@iconify/utils/lib/index.js +53 -0
- package/dist/server/node_modules/@iconify/utils/lib/loader/custom.js +32 -0
- package/dist/server/node_modules/@iconify/utils/lib/loader/loader.js +28 -0
- package/dist/server/node_modules/@iconify/utils/lib/loader/modern.js +42 -0
- package/dist/server/node_modules/@iconify/utils/lib/loader/utils.js +63 -0
- package/dist/server/node_modules/@iconify/utils/lib/misc/objects.js +27 -0
- package/dist/server/node_modules/@iconify/utils/lib/misc/strings.js +27 -0
- package/dist/server/node_modules/@iconify/utils/lib/misc/title.js +10 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/build.js +115 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/defs.js +32 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/encode-svg-for-css.js +15 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/html.js +10 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/id.js +42 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/inner-html.js +23 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/parse.js +69 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/pretty.js +55 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/size.js +28 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/trim.js +8 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/url.js +23 -0
- package/dist/server/node_modules/@iconify/utils/lib/svg/viewbox.js +9 -0
- package/dist/server/node_modules/@iconify/utils/package.json +118 -0
- package/dist/server/node_modules/@lonewolfyx/utils/dist/index.mjs +63 -0
- package/dist/server/node_modules/@lonewolfyx/utils/package.json +64 -0
- package/dist/server/node_modules/@vue/compiler-core/dist/compiler-core.cjs.prod.js +6763 -0
- package/dist/server/node_modules/@vue/compiler-core/package.json +58 -0
- package/dist/server/node_modules/@vue/compiler-dom/dist/compiler-dom.cjs.prod.js +689 -0
- package/dist/server/node_modules/@vue/compiler-dom/package.json +57 -0
- package/dist/server/node_modules/@vue/compiler-ssr/dist/compiler-ssr.cjs.js +1413 -0
- package/dist/server/node_modules/@vue/compiler-ssr/package.json +34 -0
- package/dist/server/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js +1877 -0
- package/dist/server/node_modules/@vue/reactivity/package.json +55 -0
- package/dist/server/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js +6856 -0
- package/dist/server/node_modules/@vue/runtime-core/package.json +52 -0
- package/dist/server/node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.prod.js +1796 -0
- package/dist/server/node_modules/@vue/runtime-dom/package.json +60 -0
- package/dist/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js +883 -0
- package/dist/server/node_modules/@vue/server-renderer/package.json +55 -0
- package/dist/server/{chunks/_/shared.cjs.prod.mjs → node_modules/@vue/shared/dist/shared.cjs.prod.js} +76 -81
- package/dist/server/node_modules/@vue/shared/package.json +47 -0
- package/dist/server/node_modules/better-sqlite3/build/Release/better_sqlite3.node +0 -0
- package/dist/server/node_modules/better-sqlite3/lib/database.js +90 -0
- package/dist/server/node_modules/better-sqlite3/lib/index.js +3 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/function.js +31 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/table.js +189 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
- package/dist/server/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
- package/dist/server/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
- package/dist/server/node_modules/better-sqlite3/lib/util.js +12 -0
- package/dist/server/node_modules/better-sqlite3/package.json +59 -0
- package/dist/server/node_modules/bindings/bindings.js +221 -0
- package/dist/server/node_modules/bindings/package.json +28 -0
- package/dist/server/node_modules/chokidar/handler.js +632 -0
- package/dist/server/node_modules/chokidar/index.js +822 -0
- package/dist/server/node_modules/chokidar/package.json +63 -0
- package/dist/server/{chunks/_ → node_modules/consola/dist/chunks}/prompt.mjs +2 -1
- package/dist/server/node_modules/consola/dist/core.mjs +512 -0
- package/dist/server/node_modules/consola/dist/index.mjs +651 -0
- package/dist/server/node_modules/consola/dist/shared/consola.DRwqZj3T.mjs +72 -0
- package/dist/server/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs +288 -0
- package/dist/server/node_modules/consola/package.json +136 -0
- package/dist/server/node_modules/devalue/index.js +4 -0
- package/dist/server/node_modules/devalue/package.json +40 -0
- package/dist/server/node_modules/devalue/src/base64.js +60 -0
- package/dist/server/node_modules/devalue/src/constants.js +7 -0
- package/dist/server/node_modules/devalue/src/parse.js +268 -0
- package/dist/server/node_modules/devalue/src/stringify.js +335 -0
- package/dist/server/node_modules/devalue/src/uneval.js +552 -0
- package/dist/server/node_modules/devalue/src/utils.js +144 -0
- package/dist/server/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
- package/dist/server/node_modules/entities/dist/commonjs/decode.js +568 -0
- package/dist/server/node_modules/entities/dist/commonjs/generated/decode-data-html.js +7 -0
- package/dist/server/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +7 -0
- package/dist/server/node_modules/entities/dist/commonjs/internal/bin-trie-flags.js +21 -0
- package/dist/server/node_modules/entities/dist/commonjs/internal/decode-shared.js +31 -0
- package/dist/server/node_modules/entities/dist/commonjs/package.json +3 -0
- package/dist/server/node_modules/entities/package.json +120 -0
- package/dist/server/node_modules/estree-walker/dist/umd/estree-walker.js +344 -0
- package/dist/server/node_modules/estree-walker/package.json +37 -0
- package/dist/server/node_modules/file-uri-to-path/index.js +66 -0
- package/dist/server/node_modules/file-uri-to-path/package.json +32 -0
- package/dist/server/node_modules/glob/dist/esm/index.min.js +4 -0
- package/dist/server/node_modules/glob/dist/esm/package.json +3 -0
- package/dist/server/node_modules/glob/package.json +98 -0
- package/dist/server/node_modules/hookable/dist/index.mjs +257 -0
- package/dist/server/node_modules/hookable/package.json +53 -0
- package/dist/server/node_modules/md5-typescript/dist/bundles/bundle.umd.js +208 -0
- package/dist/server/node_modules/md5-typescript/package.json +31 -0
- package/dist/server/node_modules/path-type/index.js +42 -0
- package/dist/server/node_modules/path-type/package.json +51 -0
- package/dist/server/node_modules/readdirp/index.js +272 -0
- package/dist/server/node_modules/readdirp/package.json +66 -0
- package/dist/server/node_modules/source-map-js/lib/array-set.js +121 -0
- package/dist/server/node_modules/source-map-js/lib/base64-vlq.js +140 -0
- package/dist/server/node_modules/source-map-js/lib/base64.js +67 -0
- package/dist/server/node_modules/source-map-js/lib/binary-search.js +111 -0
- package/dist/server/node_modules/source-map-js/lib/mapping-list.js +79 -0
- package/dist/server/node_modules/source-map-js/lib/quick-sort.js +132 -0
- package/dist/server/node_modules/source-map-js/lib/source-map-consumer.js +1188 -0
- package/dist/server/node_modules/source-map-js/lib/source-map-generator.js +444 -0
- package/dist/server/node_modules/source-map-js/lib/source-node.js +413 -0
- package/dist/server/node_modules/source-map-js/lib/util.js +594 -0
- package/dist/server/node_modules/source-map-js/package.json +71 -0
- package/dist/server/node_modules/source-map-js/source-map.js +8 -0
- package/dist/server/node_modules/ufo/dist/index.mjs +645 -0
- package/dist/server/node_modules/ufo/package.json +48 -0
- package/dist/server/node_modules/unhead/dist/parser.mjs +508 -0
- package/dist/server/node_modules/unhead/dist/plugins.mjs +101 -0
- package/dist/server/node_modules/unhead/dist/server.mjs +180 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.B5FWS6X0.mjs +207 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.BYvz9V1x.mjs +43 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.CbpEuj3y.mjs +71 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.Ct24BOby.mjs +182 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.D4vSFytZ.mjs +236 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.DQc16pHI.mjs +196 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.TxTMM7cM.mjs +166 -0
- package/dist/server/node_modules/unhead/dist/shared/unhead.yem5I2v_.mjs +38 -0
- package/dist/server/node_modules/unhead/dist/utils.mjs +5 -0
- package/dist/server/node_modules/unhead/package.json +105 -0
- package/dist/server/node_modules/vue/dist/vue.cjs.js +80 -0
- package/dist/server/node_modules/vue/dist/vue.cjs.prod.js +66 -0
- package/dist/server/node_modules/vue/index.js +7 -0
- package/dist/server/node_modules/vue/index.mjs +1 -0
- package/dist/server/node_modules/vue/package.json +112 -0
- package/dist/server/node_modules/vue/server-renderer/index.mjs +1 -0
- package/dist/server/node_modules/vue-bundle-renderer/dist/runtime.mjs +301 -0
- package/dist/server/node_modules/vue-bundle-renderer/package.json +55 -0
- package/dist/server/package.json +37 -0
- package/package.json +3 -1
- package/dist/public/_nuxt/B-VlGWDb.js +0 -21
- package/dist/public/_nuxt/C0azgqnZ.js +0 -1
- package/dist/public/_nuxt/CMNdiQCa.js +0 -1
- package/dist/public/_nuxt/CPuXQJE_.js +0 -1
- package/dist/public/_nuxt/DenksPSi.js +0 -119
- package/dist/public/_nuxt/Dkya5WaL.js +0 -9
- package/dist/public/_nuxt/HN9OZyaQ.js +0 -25
- package/dist/public/_nuxt/JtK-nXxy.js +0 -1
- package/dist/public/_nuxt/builds/meta/37e8bb21-a086-45bf-93dc-47eeeada7299.json +0 -1
- package/dist/public/_nuxt/entry.r-q4oQC0.css +0 -1
- package/dist/public/_nuxt/error-404.B0EXnOcv.css +0 -1
- package/dist/public/_nuxt/error-500.CnSNZoEG.css +0 -1
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { decode64 } from './base64.js';
|
|
2
|
+
import {
|
|
3
|
+
HOLE,
|
|
4
|
+
NAN,
|
|
5
|
+
NEGATIVE_INFINITY,
|
|
6
|
+
NEGATIVE_ZERO,
|
|
7
|
+
POSITIVE_INFINITY,
|
|
8
|
+
SPARSE,
|
|
9
|
+
UNDEFINED
|
|
10
|
+
} from './constants.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Revive a value serialized with `devalue.stringify`
|
|
14
|
+
* @param {string} serialized
|
|
15
|
+
* @param {Record<string, (value: any) => any>} [revivers]
|
|
16
|
+
*/
|
|
17
|
+
export function parse(serialized, revivers) {
|
|
18
|
+
return unflatten(JSON.parse(serialized), revivers);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Revive a value flattened with `devalue.stringify`
|
|
23
|
+
* @param {number | any[]} parsed
|
|
24
|
+
* @param {Record<string, (value: any) => any>} [revivers]
|
|
25
|
+
*/
|
|
26
|
+
export function unflatten(parsed, revivers) {
|
|
27
|
+
if (typeof parsed === 'number') return hydrate(parsed, true);
|
|
28
|
+
|
|
29
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
30
|
+
throw new Error('Invalid input');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const values = /** @type {any[]} */ (parsed);
|
|
34
|
+
|
|
35
|
+
const hydrated = Array(values.length);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A set of values currently being hydrated with custom revivers,
|
|
39
|
+
* used to detect invalid cyclical dependencies
|
|
40
|
+
* @type {Set<number> | null}
|
|
41
|
+
*/
|
|
42
|
+
let hydrating = null;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {number} index
|
|
46
|
+
* @returns {any}
|
|
47
|
+
*/
|
|
48
|
+
function hydrate(index, standalone = false) {
|
|
49
|
+
if (index === UNDEFINED) return undefined;
|
|
50
|
+
if (index === NAN) return NaN;
|
|
51
|
+
if (index === POSITIVE_INFINITY) return Infinity;
|
|
52
|
+
if (index === NEGATIVE_INFINITY) return -Infinity;
|
|
53
|
+
if (index === NEGATIVE_ZERO) return -0;
|
|
54
|
+
|
|
55
|
+
if (standalone || typeof index !== 'number') {
|
|
56
|
+
throw new Error(`Invalid input`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (index in hydrated) return hydrated[index];
|
|
60
|
+
|
|
61
|
+
const value = values[index];
|
|
62
|
+
|
|
63
|
+
if (!value || typeof value !== 'object') {
|
|
64
|
+
hydrated[index] = value;
|
|
65
|
+
} else if (Array.isArray(value)) {
|
|
66
|
+
if (typeof value[0] === 'string') {
|
|
67
|
+
const type = value[0];
|
|
68
|
+
|
|
69
|
+
const reviver = revivers && Object.hasOwn(revivers, type) ? revivers[type] : undefined;
|
|
70
|
+
|
|
71
|
+
if (reviver) {
|
|
72
|
+
let i = value[1];
|
|
73
|
+
if (typeof i !== 'number') {
|
|
74
|
+
// if it's not a number, it was serialized by a builtin reviver
|
|
75
|
+
// so we need to munge it into the format expected by a custom reviver
|
|
76
|
+
i = values.push(value[1]) - 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
hydrating ??= new Set();
|
|
80
|
+
|
|
81
|
+
if (hydrating.has(i)) {
|
|
82
|
+
throw new Error('Invalid circular reference');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
hydrating.add(i);
|
|
86
|
+
hydrated[index] = reviver(hydrate(i));
|
|
87
|
+
hydrating.delete(i);
|
|
88
|
+
|
|
89
|
+
return hydrated[index];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
switch (type) {
|
|
93
|
+
case 'Date':
|
|
94
|
+
hydrated[index] = new Date(value[1]);
|
|
95
|
+
break;
|
|
96
|
+
|
|
97
|
+
case 'Set':
|
|
98
|
+
const set = new Set();
|
|
99
|
+
hydrated[index] = set;
|
|
100
|
+
for (let i = 1; i < value.length; i += 1) {
|
|
101
|
+
set.add(hydrate(value[i]));
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
|
|
105
|
+
case 'Map':
|
|
106
|
+
const map = new Map();
|
|
107
|
+
hydrated[index] = map;
|
|
108
|
+
for (let i = 1; i < value.length; i += 2) {
|
|
109
|
+
map.set(hydrate(value[i]), hydrate(value[i + 1]));
|
|
110
|
+
}
|
|
111
|
+
break;
|
|
112
|
+
|
|
113
|
+
case 'RegExp':
|
|
114
|
+
hydrated[index] = new RegExp(value[1], value[2]);
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case 'Object': {
|
|
118
|
+
const wrapped_index = value[1];
|
|
119
|
+
|
|
120
|
+
if (
|
|
121
|
+
typeof values[wrapped_index] === 'object' &&
|
|
122
|
+
values[wrapped_index][0] !== 'BigInt'
|
|
123
|
+
) {
|
|
124
|
+
// avoid infinite recusion in case of malformed input
|
|
125
|
+
throw new Error('Invalid input');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
hydrated[index] = Object(hydrate(wrapped_index));
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case 'BigInt':
|
|
133
|
+
hydrated[index] = BigInt(value[1]);
|
|
134
|
+
break;
|
|
135
|
+
|
|
136
|
+
case 'null':
|
|
137
|
+
const obj = Object.create(null);
|
|
138
|
+
hydrated[index] = obj;
|
|
139
|
+
for (let i = 1; i < value.length; i += 2) {
|
|
140
|
+
if (value[i] === '__proto__') {
|
|
141
|
+
throw new Error('Cannot parse an object with a `__proto__` property');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
obj[value[i]] = hydrate(value[i + 1]);
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
|
|
148
|
+
case 'Int8Array':
|
|
149
|
+
case 'Uint8Array':
|
|
150
|
+
case 'Uint8ClampedArray':
|
|
151
|
+
case 'Int16Array':
|
|
152
|
+
case 'Uint16Array':
|
|
153
|
+
case 'Float16Array':
|
|
154
|
+
case 'Int32Array':
|
|
155
|
+
case 'Uint32Array':
|
|
156
|
+
case 'Float32Array':
|
|
157
|
+
case 'Float64Array':
|
|
158
|
+
case 'BigInt64Array':
|
|
159
|
+
case 'BigUint64Array':
|
|
160
|
+
case 'DataView': {
|
|
161
|
+
if (values[value[1]][0] !== 'ArrayBuffer') {
|
|
162
|
+
// without this, if we receive malformed input we could
|
|
163
|
+
// end up trying to hydrate in a circle or allocate
|
|
164
|
+
// huge amounts of memory when we call `new TypedArrayConstructor(buffer)`
|
|
165
|
+
throw new Error('Invalid data');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const TypedArrayConstructor = globalThis[type];
|
|
169
|
+
const buffer = hydrate(value[1]);
|
|
170
|
+
|
|
171
|
+
hydrated[index] =
|
|
172
|
+
value[2] !== undefined
|
|
173
|
+
? new TypedArrayConstructor(buffer, value[2], value[3])
|
|
174
|
+
: new TypedArrayConstructor(buffer);
|
|
175
|
+
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
case 'ArrayBuffer': {
|
|
180
|
+
const base64 = value[1];
|
|
181
|
+
if (typeof base64 !== 'string') {
|
|
182
|
+
throw new Error('Invalid ArrayBuffer encoding');
|
|
183
|
+
}
|
|
184
|
+
const arraybuffer = decode64(base64);
|
|
185
|
+
hydrated[index] = arraybuffer;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
case 'Temporal.Duration':
|
|
190
|
+
case 'Temporal.Instant':
|
|
191
|
+
case 'Temporal.PlainDate':
|
|
192
|
+
case 'Temporal.PlainTime':
|
|
193
|
+
case 'Temporal.PlainDateTime':
|
|
194
|
+
case 'Temporal.PlainMonthDay':
|
|
195
|
+
case 'Temporal.PlainYearMonth':
|
|
196
|
+
case 'Temporal.ZonedDateTime': {
|
|
197
|
+
const temporalName = type.slice(9);
|
|
198
|
+
// @ts-expect-error TS doesn't know about Temporal yet
|
|
199
|
+
hydrated[index] = Temporal[temporalName].from(value[1]);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
case 'URL': {
|
|
204
|
+
const url = new URL(value[1]);
|
|
205
|
+
hydrated[index] = url;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
case 'URLSearchParams': {
|
|
210
|
+
const url = new URLSearchParams(value[1]);
|
|
211
|
+
hydrated[index] = url;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
default:
|
|
216
|
+
throw new Error(`Unknown type ${type}`);
|
|
217
|
+
}
|
|
218
|
+
} else if (value[0] === SPARSE) {
|
|
219
|
+
// Sparse array encoding: [SPARSE, length, idx, val, idx, val, ...]
|
|
220
|
+
const len = value[1];
|
|
221
|
+
|
|
222
|
+
if (!Number.isInteger(len) || len < 0) {
|
|
223
|
+
throw new Error('Invalid input');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const array = new Array(len);
|
|
227
|
+
hydrated[index] = array;
|
|
228
|
+
|
|
229
|
+
for (let i = 2; i < value.length; i += 2) {
|
|
230
|
+
const idx = value[i];
|
|
231
|
+
|
|
232
|
+
if (!Number.isInteger(idx) || idx < 0 || idx >= len) {
|
|
233
|
+
throw new Error('Invalid input');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
array[idx] = hydrate(value[i + 1]);
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
const array = new Array(value.length);
|
|
240
|
+
hydrated[index] = array;
|
|
241
|
+
|
|
242
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
243
|
+
const n = value[i];
|
|
244
|
+
if (n === HOLE) continue;
|
|
245
|
+
|
|
246
|
+
array[i] = hydrate(n);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
/** @type {Record<string, any>} */
|
|
251
|
+
const object = {};
|
|
252
|
+
hydrated[index] = object;
|
|
253
|
+
|
|
254
|
+
for (const key of Object.keys(value)) {
|
|
255
|
+
if (key === '__proto__') {
|
|
256
|
+
throw new Error('Cannot parse an object with a `__proto__` property');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const n = value[key];
|
|
260
|
+
object[key] = hydrate(n);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return hydrated[index];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return hydrate(0);
|
|
268
|
+
}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DevalueError,
|
|
3
|
+
enumerable_symbols,
|
|
4
|
+
get_type,
|
|
5
|
+
is_plain_object,
|
|
6
|
+
is_primitive,
|
|
7
|
+
stringify_key,
|
|
8
|
+
stringify_string,
|
|
9
|
+
valid_array_indices
|
|
10
|
+
} from './utils.js';
|
|
11
|
+
import {
|
|
12
|
+
HOLE,
|
|
13
|
+
NAN,
|
|
14
|
+
NEGATIVE_INFINITY,
|
|
15
|
+
NEGATIVE_ZERO,
|
|
16
|
+
POSITIVE_INFINITY,
|
|
17
|
+
SPARSE,
|
|
18
|
+
UNDEFINED
|
|
19
|
+
} from './constants.js';
|
|
20
|
+
import { encode64 } from './base64.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Turn a value into a JSON string that can be parsed with `devalue.parse`
|
|
24
|
+
* @param {any} value
|
|
25
|
+
* @param {Record<string, (value: any) => any>} [reducers]
|
|
26
|
+
*/
|
|
27
|
+
export function stringify(value, reducers) {
|
|
28
|
+
/** @type {any[]} */
|
|
29
|
+
const stringified = [];
|
|
30
|
+
|
|
31
|
+
/** @type {Map<any, number>} */
|
|
32
|
+
const indexes = new Map();
|
|
33
|
+
|
|
34
|
+
/** @type {Array<{ key: string, fn: (value: any) => any }>} */
|
|
35
|
+
const custom = [];
|
|
36
|
+
if (reducers) {
|
|
37
|
+
for (const key of Object.getOwnPropertyNames(reducers)) {
|
|
38
|
+
custom.push({ key, fn: reducers[key] });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** @type {string[]} */
|
|
43
|
+
const keys = [];
|
|
44
|
+
|
|
45
|
+
let p = 0;
|
|
46
|
+
|
|
47
|
+
/** @param {any} thing */
|
|
48
|
+
function flatten(thing) {
|
|
49
|
+
if (thing === undefined) return UNDEFINED;
|
|
50
|
+
if (Number.isNaN(thing)) return NAN;
|
|
51
|
+
if (thing === Infinity) return POSITIVE_INFINITY;
|
|
52
|
+
if (thing === -Infinity) return NEGATIVE_INFINITY;
|
|
53
|
+
if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO;
|
|
54
|
+
|
|
55
|
+
if (indexes.has(thing)) return /** @type {number} */ (indexes.get(thing));
|
|
56
|
+
|
|
57
|
+
const index = p++;
|
|
58
|
+
indexes.set(thing, index);
|
|
59
|
+
|
|
60
|
+
for (const { key, fn } of custom) {
|
|
61
|
+
const value = fn(thing);
|
|
62
|
+
if (value) {
|
|
63
|
+
stringified[index] = `["${key}",${flatten(value)}]`;
|
|
64
|
+
return index;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (typeof thing === 'function') {
|
|
69
|
+
throw new DevalueError(`Cannot stringify a function`, keys, thing, value);
|
|
70
|
+
} else if (typeof thing === 'symbol') {
|
|
71
|
+
throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let str = '';
|
|
75
|
+
|
|
76
|
+
if (is_primitive(thing)) {
|
|
77
|
+
str = stringify_primitive(thing);
|
|
78
|
+
} else {
|
|
79
|
+
const type = get_type(thing);
|
|
80
|
+
|
|
81
|
+
switch (type) {
|
|
82
|
+
case 'Number':
|
|
83
|
+
case 'String':
|
|
84
|
+
case 'Boolean':
|
|
85
|
+
case 'BigInt':
|
|
86
|
+
str = `["Object",${flatten(thing.valueOf())}]`;
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case 'Date':
|
|
90
|
+
const valid = !isNaN(thing.getDate());
|
|
91
|
+
str = `["Date","${valid ? thing.toISOString() : ''}"]`;
|
|
92
|
+
break;
|
|
93
|
+
|
|
94
|
+
case 'URL':
|
|
95
|
+
str = `["URL",${stringify_string(thing.toString())}]`;
|
|
96
|
+
break;
|
|
97
|
+
|
|
98
|
+
case 'URLSearchParams':
|
|
99
|
+
str = `["URLSearchParams",${stringify_string(thing.toString())}]`;
|
|
100
|
+
break;
|
|
101
|
+
|
|
102
|
+
case 'RegExp':
|
|
103
|
+
const { source, flags } = thing;
|
|
104
|
+
str = flags
|
|
105
|
+
? `["RegExp",${stringify_string(source)},"${flags}"]`
|
|
106
|
+
: `["RegExp",${stringify_string(source)}]`;
|
|
107
|
+
break;
|
|
108
|
+
|
|
109
|
+
case 'Array': {
|
|
110
|
+
// For dense arrays (no holes), we iterate normally.
|
|
111
|
+
// When we encounter the first hole, we call Object.keys
|
|
112
|
+
// to determine the sparseness, then decide between:
|
|
113
|
+
// - HOLE encoding: [-2, val, -2, ...] (default)
|
|
114
|
+
// - Sparse encoding: [-7, length, idx, val, ...] (for very sparse arrays)
|
|
115
|
+
// Only the sparse path avoids iterating every slot, which
|
|
116
|
+
// is what protects against the DoS of e.g. `arr[1000000] = 1`.
|
|
117
|
+
let mostly_dense = false;
|
|
118
|
+
|
|
119
|
+
str = '[';
|
|
120
|
+
|
|
121
|
+
for (let i = 0; i < thing.length; i += 1) {
|
|
122
|
+
if (i > 0) str += ',';
|
|
123
|
+
|
|
124
|
+
if (Object.hasOwn(thing, i)) {
|
|
125
|
+
keys.push(`[${i}]`);
|
|
126
|
+
str += flatten(thing[i]);
|
|
127
|
+
keys.pop();
|
|
128
|
+
} else if (mostly_dense) {
|
|
129
|
+
// Use dense encoding. The heuristic guarantees the
|
|
130
|
+
// array is only mildly sparse, so iterating over every
|
|
131
|
+
// slot is fine.
|
|
132
|
+
str += HOLE;
|
|
133
|
+
} else {
|
|
134
|
+
// Decide between HOLE encoding and sparse encoding.
|
|
135
|
+
//
|
|
136
|
+
// HOLE encoding: each hole is serialized as the HOLE
|
|
137
|
+
// sentinel (-2). For example, [, "a", ,] becomes
|
|
138
|
+
// [-2, 0, -2]. Each hole costs 3 chars ("-2" + comma).
|
|
139
|
+
//
|
|
140
|
+
// Sparse encoding: lists only populated indices.
|
|
141
|
+
// For example, [, "a", ,] becomes [-7, 3, 1, 0] — the
|
|
142
|
+
// -7 sentinel, the array length (3), then index-value
|
|
143
|
+
// pairs. This avoids paying per-hole, but each element
|
|
144
|
+
// costs extra chars to write its index.
|
|
145
|
+
//
|
|
146
|
+
// The values are the same size either way, so the
|
|
147
|
+
// choice comes down to structural overhead:
|
|
148
|
+
//
|
|
149
|
+
// HOLE overhead:
|
|
150
|
+
// 3 chars per hole ("-2" + comma)
|
|
151
|
+
// = (L - P) * 3
|
|
152
|
+
//
|
|
153
|
+
// Sparse overhead:
|
|
154
|
+
// "-7," — 3 chars (sparse sentinel + comma)
|
|
155
|
+
// + length + "," — (d + 1) chars (array length + comma)
|
|
156
|
+
// + per element: index + "," — (d + 1) chars
|
|
157
|
+
// = (4 + d) + P * (d + 1)
|
|
158
|
+
//
|
|
159
|
+
// where L is the array length, P is the number of
|
|
160
|
+
// populated elements, and d is the number of digits
|
|
161
|
+
// in L (an upper bound on the digits in any index).
|
|
162
|
+
//
|
|
163
|
+
// Sparse encoding is cheaper when:
|
|
164
|
+
// (4 + d) + P * (d + 1) < (L - P) * 3
|
|
165
|
+
const populated_keys = valid_array_indices(/** @type {any[]} */ (thing));
|
|
166
|
+
const population = populated_keys.length;
|
|
167
|
+
const d = String(thing.length).length;
|
|
168
|
+
|
|
169
|
+
const hole_cost = (thing.length - population) * 3;
|
|
170
|
+
const sparse_cost = 4 + d + population * (d + 1);
|
|
171
|
+
|
|
172
|
+
if (hole_cost > sparse_cost) {
|
|
173
|
+
str = '[' + SPARSE + ',' + thing.length;
|
|
174
|
+
for (let j = 0; j < populated_keys.length; j++) {
|
|
175
|
+
const key = populated_keys[j];
|
|
176
|
+
keys.push(`[${key}]`);
|
|
177
|
+
str += ',' + key + ',' + flatten(thing[key]);
|
|
178
|
+
keys.pop();
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
} else {
|
|
182
|
+
mostly_dense = true;
|
|
183
|
+
str += HOLE;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
str += ']';
|
|
189
|
+
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
case 'Set':
|
|
194
|
+
str = '["Set"';
|
|
195
|
+
|
|
196
|
+
for (const value of thing) {
|
|
197
|
+
str += `,${flatten(value)}`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
str += ']';
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case 'Map':
|
|
204
|
+
str = '["Map"';
|
|
205
|
+
|
|
206
|
+
for (const [key, value] of thing) {
|
|
207
|
+
keys.push(`.get(${is_primitive(key) ? stringify_primitive(key) : '...'})`);
|
|
208
|
+
str += `,${flatten(key)},${flatten(value)}`;
|
|
209
|
+
keys.pop();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
str += ']';
|
|
213
|
+
break;
|
|
214
|
+
|
|
215
|
+
case 'Int8Array':
|
|
216
|
+
case 'Uint8Array':
|
|
217
|
+
case 'Uint8ClampedArray':
|
|
218
|
+
case 'Int16Array':
|
|
219
|
+
case 'Uint16Array':
|
|
220
|
+
case 'Float16Array':
|
|
221
|
+
case 'Int32Array':
|
|
222
|
+
case 'Uint32Array':
|
|
223
|
+
case 'Float32Array':
|
|
224
|
+
case 'Float64Array':
|
|
225
|
+
case 'BigInt64Array':
|
|
226
|
+
case 'BigUint64Array':
|
|
227
|
+
case 'DataView': {
|
|
228
|
+
/** @type {import("./types.js").TypedArray} */
|
|
229
|
+
const typedArray = thing;
|
|
230
|
+
str = '["' + type + '",' + flatten(typedArray.buffer);
|
|
231
|
+
|
|
232
|
+
// handle subarrays
|
|
233
|
+
if (typedArray.byteLength !== typedArray.buffer.byteLength) {
|
|
234
|
+
// to be used with `new TypedArray(buffer, byteOffset, length)`
|
|
235
|
+
str += `,${typedArray.byteOffset},${typedArray.length}`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
str += ']';
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
case 'ArrayBuffer': {
|
|
243
|
+
/** @type {ArrayBuffer} */
|
|
244
|
+
const arraybuffer = thing;
|
|
245
|
+
const base64 = encode64(arraybuffer);
|
|
246
|
+
|
|
247
|
+
str = `["ArrayBuffer","${base64}"]`;
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
case 'Temporal.Duration':
|
|
252
|
+
case 'Temporal.Instant':
|
|
253
|
+
case 'Temporal.PlainDate':
|
|
254
|
+
case 'Temporal.PlainTime':
|
|
255
|
+
case 'Temporal.PlainDateTime':
|
|
256
|
+
case 'Temporal.PlainMonthDay':
|
|
257
|
+
case 'Temporal.PlainYearMonth':
|
|
258
|
+
case 'Temporal.ZonedDateTime':
|
|
259
|
+
str = `["${type}",${stringify_string(thing.toString())}]`;
|
|
260
|
+
break;
|
|
261
|
+
|
|
262
|
+
default:
|
|
263
|
+
if (!is_plain_object(thing)) {
|
|
264
|
+
throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys, thing, value);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (enumerable_symbols(thing).length > 0) {
|
|
268
|
+
throw new DevalueError(`Cannot stringify POJOs with symbolic keys`, keys, thing, value);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (Object.getPrototypeOf(thing) === null) {
|
|
272
|
+
str = '["null"';
|
|
273
|
+
for (const key of Object.keys(thing)) {
|
|
274
|
+
if (key === '__proto__') {
|
|
275
|
+
throw new DevalueError(
|
|
276
|
+
`Cannot stringify objects with __proto__ keys`,
|
|
277
|
+
keys,
|
|
278
|
+
thing,
|
|
279
|
+
value
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
keys.push(stringify_key(key));
|
|
284
|
+
str += `,${stringify_string(key)},${flatten(thing[key])}`;
|
|
285
|
+
keys.pop();
|
|
286
|
+
}
|
|
287
|
+
str += ']';
|
|
288
|
+
} else {
|
|
289
|
+
str = '{';
|
|
290
|
+
let started = false;
|
|
291
|
+
for (const key of Object.keys(thing)) {
|
|
292
|
+
if (key === '__proto__') {
|
|
293
|
+
throw new DevalueError(
|
|
294
|
+
`Cannot stringify objects with __proto__ keys`,
|
|
295
|
+
keys,
|
|
296
|
+
thing,
|
|
297
|
+
value
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (started) str += ',';
|
|
302
|
+
started = true;
|
|
303
|
+
keys.push(stringify_key(key));
|
|
304
|
+
str += `${stringify_string(key)}:${flatten(thing[key])}`;
|
|
305
|
+
keys.pop();
|
|
306
|
+
}
|
|
307
|
+
str += '}';
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
stringified[index] = str;
|
|
313
|
+
return index;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const index = flatten(value);
|
|
317
|
+
|
|
318
|
+
// special case — value is represented as a negative index
|
|
319
|
+
if (index < 0) return `${index}`;
|
|
320
|
+
|
|
321
|
+
return `[${stringified.join(',')}]`;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @param {any} thing
|
|
326
|
+
* @returns {string}
|
|
327
|
+
*/
|
|
328
|
+
function stringify_primitive(thing) {
|
|
329
|
+
const type = typeof thing;
|
|
330
|
+
if (type === 'string') return stringify_string(thing);
|
|
331
|
+
if (thing === void 0) return UNDEFINED.toString();
|
|
332
|
+
if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO.toString();
|
|
333
|
+
if (type === 'bigint') return `["BigInt","${thing}"]`;
|
|
334
|
+
return String(thing);
|
|
335
|
+
}
|