@bitcobblers/wod-wiki-wql 0.35.2116 → 0.35.2119
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.cjs +236 -233
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -47
- package/dist/index.d.ts +26 -47
- package/dist/index.mjs +238 -232
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KNOWN_OUTPUT_TYPES, dimensionKeyOf, convertViaCatalog, systemDefaultUnit, MetricType, valueKindOf, normalizeFieldPath, fieldRefKey, normalizeFieldComponent } from '@bitcobblers/wod-wiki-core';
|
|
1
|
+
import { KNOWN_OUTPUT_TYPES, dimensionKeyOf, convertViaCatalog, systemDefaultUnit, MetricType, valueKindOf, normalizeFieldPath, validateNoteBlocks, fieldRefKey, normalizeFieldComponent } from '@bitcobblers/wod-wiki-core';
|
|
2
2
|
export { SYSTEM_DEFAULT_OUTPUT_UNIT, UnitConversionError, convertViaCatalog, dimensionKeyOf, lookupUnit, systemDefaultUnit } from '@bitcobblers/wod-wiki-core';
|
|
3
3
|
import { LRParser } from '@lezer/lr';
|
|
4
4
|
import { LRLanguage, HighlightStyle, LanguageSupport, syntaxHighlighting } from '@codemirror/language';
|
|
@@ -653,10 +653,10 @@ function validateSourceFilter(filters) {
|
|
|
653
653
|
if (val === "collection" || val === "collections") {
|
|
654
654
|
return `source:${val} is retired \u2014 collections were renamed to feeds; use source:feeds or :feed{}.`;
|
|
655
655
|
}
|
|
656
|
-
if (WQL_SOURCE_VALUES.includes(val) || val === "feed" || val.startsWith("collection:")) {
|
|
656
|
+
if (WQL_SOURCE_VALUES.includes(val) || val === "feed" || val.startsWith("collection:") || val.startsWith("feed:")) {
|
|
657
657
|
continue;
|
|
658
658
|
}
|
|
659
|
-
return `Unknown source "${val}". Try: ${WQL_SOURCE_VALUES.join(", ")} (or collection:<id>)`;
|
|
659
|
+
return `Unknown source "${val}". Try: ${WQL_SOURCE_VALUES.join(", ")} (or collection:<id>, feed:<id>)`;
|
|
660
660
|
}
|
|
661
661
|
}
|
|
662
662
|
return void 0;
|
|
@@ -1143,9 +1143,7 @@ function findTargetAdvisories(query) {
|
|
|
1143
1143
|
if (query.groupBy?.length) {
|
|
1144
1144
|
const dimensions = wqlGroupingDimensions(target, "find");
|
|
1145
1145
|
const unsupported = query.groupBy.filter((dim) => !dimensions.some((d) => d.toLowerCase() === dim.toLowerCase()));
|
|
1146
|
-
if (target === "note" || target === "block") {
|
|
1147
|
-
if (unsupported.length) advisories.push(`:${target} cannot group by ${unsupported.join(", ")}; grouped by tag instead. Valid alternatives: ${dimensions.join(", ")}.`);
|
|
1148
|
-
} else if (target === "segment" || target === "event") {
|
|
1146
|
+
if (target === "note" || target === "block") ; else if (target === "segment" || target === "event") {
|
|
1149
1147
|
const selected = query.pipes?.select?.map((column) => column.col);
|
|
1150
1148
|
const unavailable = query.groupBy.filter((dim) => selected ? !selected.includes(dim) : !dimensions.includes(dim));
|
|
1151
1149
|
if (unavailable.length) advisories.push(`:${target} groups only emitted table columns; ${unavailable.join(", ")} may be unassigned. Select each grouping column explicitly.`);
|
|
@@ -2591,8 +2589,8 @@ function normalizeSummaryFacts(logs, identity) {
|
|
|
2591
2589
|
origin: identity.origin,
|
|
2592
2590
|
pageId: identity.pageId,
|
|
2593
2591
|
grain: "summary",
|
|
2594
|
-
|
|
2595
|
-
|
|
2592
|
+
blockId: identity.blockId ?? "",
|
|
2593
|
+
blockVersion: identity.blockVersion ?? 0,
|
|
2596
2594
|
resultId: identity.resultId,
|
|
2597
2595
|
type: f.metricKey,
|
|
2598
2596
|
value: f.value,
|
|
@@ -2644,8 +2642,8 @@ function toEventRows(logs, identity) {
|
|
|
2644
2642
|
text: output.text,
|
|
2645
2643
|
dialect: output.dialect,
|
|
2646
2644
|
completionReason: output.completionReason,
|
|
2647
|
-
|
|
2648
|
-
|
|
2645
|
+
blockId: identity.blockId,
|
|
2646
|
+
blockVersion: identity.blockVersion
|
|
2649
2647
|
}));
|
|
2650
2648
|
}
|
|
2651
2649
|
function toSummaryEventRows(logs, identity) {
|
|
@@ -2692,8 +2690,8 @@ function toSummaryEventRows(logs, identity) {
|
|
|
2692
2690
|
...f.grade ? { grade: f.grade } : {}
|
|
2693
2691
|
}
|
|
2694
2692
|
}],
|
|
2695
|
-
|
|
2696
|
-
|
|
2693
|
+
blockId: identity.blockId,
|
|
2694
|
+
blockVersion: identity.blockVersion
|
|
2697
2695
|
}));
|
|
2698
2696
|
}
|
|
2699
2697
|
function projectEventToFacts(record) {
|
|
@@ -2712,8 +2710,8 @@ function projectEventToFacts(record) {
|
|
|
2712
2710
|
origin: record.origin,
|
|
2713
2711
|
pageId: record.pageId,
|
|
2714
2712
|
grain: "summary",
|
|
2715
|
-
|
|
2716
|
-
|
|
2713
|
+
blockId: record.blockId ?? "",
|
|
2714
|
+
blockVersion: record.blockVersion ?? 0,
|
|
2717
2715
|
resultId: record.resultId,
|
|
2718
2716
|
type: metricKey,
|
|
2719
2717
|
value: m.value,
|
|
@@ -2771,8 +2769,8 @@ function projectEventToFacts(record) {
|
|
|
2771
2769
|
origin: record.origin,
|
|
2772
2770
|
pageId: record.pageId,
|
|
2773
2771
|
grain: "event",
|
|
2774
|
-
|
|
2775
|
-
|
|
2772
|
+
blockId: record.blockId ?? "",
|
|
2773
|
+
blockVersion: record.blockVersion ?? 0,
|
|
2776
2774
|
resultId: record.resultId,
|
|
2777
2775
|
type: metricKey,
|
|
2778
2776
|
value: m.value,
|
|
@@ -2814,117 +2812,6 @@ function eventsToStoredLogs(events) {
|
|
|
2814
2812
|
}));
|
|
2815
2813
|
}
|
|
2816
2814
|
|
|
2817
|
-
// src/dashboard/frontmatter.ts
|
|
2818
|
-
var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
2819
|
-
function unquote(value) {
|
|
2820
|
-
return value.replace(
|
|
2821
|
-
/^(['"])(.*)\1$/,
|
|
2822
|
-
(_match, quote, inner) => quote === '"' ? inner.replace(/\\(["\\])/g, "$1") : inner
|
|
2823
|
-
);
|
|
2824
|
-
}
|
|
2825
|
-
function parseFrontmatter(raw) {
|
|
2826
|
-
const match = raw.match(FRONTMATTER_RE);
|
|
2827
|
-
if (!match) return { meta: {}, body: raw };
|
|
2828
|
-
return { meta: parseMetaLines(match[1].split(/\r?\n/)), body: raw.slice(match[0].length) };
|
|
2829
|
-
}
|
|
2830
|
-
function parseMetaLines(lines) {
|
|
2831
|
-
const meta = {};
|
|
2832
|
-
for (let i = 0; i < lines.length; i++) {
|
|
2833
|
-
const keyMatch = lines[i].match(/^([A-Za-z][\w.-]*)\s*:(.*)$/);
|
|
2834
|
-
if (!keyMatch) continue;
|
|
2835
|
-
const key = keyMatch[1];
|
|
2836
|
-
const rawVal = keyMatch[2].trim();
|
|
2837
|
-
if (rawVal === "") {
|
|
2838
|
-
const items = [];
|
|
2839
|
-
while (i + 1 < lines.length) {
|
|
2840
|
-
const itemMatch = lines[i + 1].match(/^\s+-\s+(.+)$/);
|
|
2841
|
-
if (!itemMatch) break;
|
|
2842
|
-
items.push(itemMatch[1].trim());
|
|
2843
|
-
i++;
|
|
2844
|
-
}
|
|
2845
|
-
meta[key] = items.length > 0 ? items : "";
|
|
2846
|
-
} else {
|
|
2847
|
-
const wasQuoted = /^(['"])(.*)\1$/.test(rawVal);
|
|
2848
|
-
const value = unquote(rawVal);
|
|
2849
|
-
const num = Number(value);
|
|
2850
|
-
meta[key] = !wasQuoted && value !== "" && !isNaN(num) ? num : value;
|
|
2851
|
-
}
|
|
2852
|
-
}
|
|
2853
|
-
return meta;
|
|
2854
|
-
}
|
|
2855
|
-
function parseFrontmatterBody(innerContent) {
|
|
2856
|
-
return parseMetaLines(innerContent.split(/\r?\n/));
|
|
2857
|
-
}
|
|
2858
|
-
function quoteYamlScalar(value) {
|
|
2859
|
-
if (value === "") return '""';
|
|
2860
|
-
const looksNumeric = !isNaN(Number(value));
|
|
2861
|
-
const looksKeyword = /^(true|false|null|yes|no|on|off)$/i.test(value);
|
|
2862
|
-
if (/[":'\n#{}[\\],&*?|<>=%!@`]/.test(value) || value !== value.trim() || value.startsWith("-") || looksNumeric || looksKeyword) {
|
|
2863
|
-
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
2864
|
-
}
|
|
2865
|
-
return value;
|
|
2866
|
-
}
|
|
2867
|
-
function serializeFrontmatter(meta) {
|
|
2868
|
-
const lines = [];
|
|
2869
|
-
for (const [key, value] of Object.entries(meta)) {
|
|
2870
|
-
if (Array.isArray(value)) {
|
|
2871
|
-
if (value.length === 0) {
|
|
2872
|
-
lines.push(`${key}: ""`);
|
|
2873
|
-
continue;
|
|
2874
|
-
}
|
|
2875
|
-
lines.push(`${key}:`);
|
|
2876
|
-
for (const item of value) {
|
|
2877
|
-
lines.push(` - ${quoteYamlScalar(item)}`);
|
|
2878
|
-
}
|
|
2879
|
-
} else if (typeof value === "number") {
|
|
2880
|
-
lines.push(`${key}: ${value}`);
|
|
2881
|
-
} else {
|
|
2882
|
-
lines.push(`${key}: ${quoteYamlScalar(value)}`);
|
|
2883
|
-
}
|
|
2884
|
-
}
|
|
2885
|
-
return lines.join("\n");
|
|
2886
|
-
}
|
|
2887
|
-
function stripFrontmatter(raw) {
|
|
2888
|
-
return parseFrontmatter(raw).body;
|
|
2889
|
-
}
|
|
2890
|
-
function getScalar(meta, key) {
|
|
2891
|
-
const value = meta[key];
|
|
2892
|
-
return typeof value === "string" || typeof value === "number" ? value : void 0;
|
|
2893
|
-
}
|
|
2894
|
-
function getList(meta, key) {
|
|
2895
|
-
const value = meta[key];
|
|
2896
|
-
return Array.isArray(value) ? value : [];
|
|
2897
|
-
}
|
|
2898
|
-
function parseFrontmatterCategories(raw) {
|
|
2899
|
-
return getList(parseFrontmatter(raw).meta, "category").map((c) => c.toLowerCase());
|
|
2900
|
-
}
|
|
2901
|
-
function extractFrontmatterTags(raw) {
|
|
2902
|
-
const meta = FRONTMATTER_RE.test(raw) ? parseFrontmatter(raw).meta : parseFrontmatterBody(raw);
|
|
2903
|
-
const tags = meta["tags"];
|
|
2904
|
-
const list = Array.isArray(tags) ? tags : typeof tags === "string" && tags.trim() ? tags.trim().startsWith("[") && tags.trim().endsWith("]") ? tags.trim().slice(1, -1).split(",") : [tags] : [];
|
|
2905
|
-
return [...new Set(list.map((tag) => tag.trim()).filter(Boolean))];
|
|
2906
|
-
}
|
|
2907
|
-
function parseFlatProperties(innerContent) {
|
|
2908
|
-
const props = {};
|
|
2909
|
-
for (const line of innerContent.split(/\r?\n/)) {
|
|
2910
|
-
const match = line.match(/^([^:]+):\s*(.*)$/);
|
|
2911
|
-
if (match) {
|
|
2912
|
-
props[match[1].trim()] = match[2].trim();
|
|
2913
|
-
}
|
|
2914
|
-
}
|
|
2915
|
-
return props;
|
|
2916
|
-
}
|
|
2917
|
-
function parseFrontmatterProps(lines) {
|
|
2918
|
-
const props = {};
|
|
2919
|
-
for (const line of lines) {
|
|
2920
|
-
const match = line.match(/^([^:]+):\s*(.*)$/);
|
|
2921
|
-
if (match) {
|
|
2922
|
-
props[match[1].trim()] = match[2].trim();
|
|
2923
|
-
}
|
|
2924
|
-
}
|
|
2925
|
-
return props;
|
|
2926
|
-
}
|
|
2927
|
-
|
|
2928
2815
|
// src/selection.ts
|
|
2929
2816
|
function partitionKey(coverage, effortSlug) {
|
|
2930
2817
|
const tags = coverage?.groupTags ? Object.entries(coverage.groupTags).sort(([a], [b]) => a < b ? -1 : 1).map(([k, v]) => `${k}=${v}`).join(",") : "";
|
|
@@ -3044,6 +2931,12 @@ function sourceMatches(item, kind) {
|
|
|
3044
2931
|
if (kind === "playground") {
|
|
3045
2932
|
return sourceId === "playground" || item.type === "playground";
|
|
3046
2933
|
}
|
|
2934
|
+
if (kind.startsWith("feed:")) {
|
|
2935
|
+
const rest = kind.slice("feed:".length).replace(/^feeds\//, "");
|
|
2936
|
+
if (!rest || !sourceId?.startsWith("feed:")) return false;
|
|
2937
|
+
const idRest = sourceId.slice("feed:".length).replace(/^feeds\//, "");
|
|
2938
|
+
return idRest === rest || idRest.startsWith(`${rest}/`);
|
|
2939
|
+
}
|
|
3047
2940
|
return sourceId === kind;
|
|
3048
2941
|
}
|
|
3049
2942
|
function applySourceFilter(items, filters) {
|
|
@@ -3398,7 +3291,6 @@ var QueryService = class {
|
|
|
3398
3291
|
noteStore;
|
|
3399
3292
|
blockStore;
|
|
3400
3293
|
effortStore;
|
|
3401
|
-
staticNoteStore;
|
|
3402
3294
|
pageStore;
|
|
3403
3295
|
relationStore;
|
|
3404
3296
|
datasetStore;
|
|
@@ -3413,14 +3305,13 @@ var QueryService = class {
|
|
|
3413
3305
|
noteTagsStore = {
|
|
3414
3306
|
getAllFromIndex: async () => []
|
|
3415
3307
|
};
|
|
3416
|
-
constructor(storesOrEventStore, noteStore, blockStore, effortStore
|
|
3417
|
-
if (storesOrEventStore && typeof storesOrEventStore === "object" && ("eventStore" in storesOrEventStore || "noteStore" in storesOrEventStore || "blockStore" in storesOrEventStore || "effortStore" in storesOrEventStore || "
|
|
3308
|
+
constructor(storesOrEventStore, noteStore, blockStore, effortStore) {
|
|
3309
|
+
if (storesOrEventStore && typeof storesOrEventStore === "object" && ("eventStore" in storesOrEventStore || "noteStore" in storesOrEventStore || "blockStore" in storesOrEventStore || "effortStore" in storesOrEventStore || "pageStore" in storesOrEventStore || "relationStore" in storesOrEventStore || "datasetStore" in storesOrEventStore)) {
|
|
3418
3310
|
const stores = storesOrEventStore;
|
|
3419
3311
|
this.store = stores.eventStore ?? defaultEventStore;
|
|
3420
3312
|
this.noteStore = stores.noteStore ?? defaultNoteStore;
|
|
3421
3313
|
this.blockStore = stores.blockStore ?? defaultBlockStore;
|
|
3422
3314
|
this.effortStore = stores.effortStore ?? defaultEffortStore;
|
|
3423
|
-
this.staticNoteStore = stores.staticNoteStore;
|
|
3424
3315
|
this.pageStore = stores.pageStore;
|
|
3425
3316
|
this.relationStore = stores.relationStore;
|
|
3426
3317
|
this.datasetStore = stores.datasetStore;
|
|
@@ -3432,7 +3323,6 @@ var QueryService = class {
|
|
|
3432
3323
|
this.noteStore = noteStore ?? defaultNoteStore;
|
|
3433
3324
|
this.blockStore = blockStore ?? defaultBlockStore;
|
|
3434
3325
|
this.effortStore = effortStore ?? defaultEffortStore;
|
|
3435
|
-
this.staticNoteStore = staticNoteStore;
|
|
3436
3326
|
}
|
|
3437
3327
|
}
|
|
3438
3328
|
/** Windowed flat-fact fetch — the projected view over the event store. */
|
|
@@ -3752,14 +3642,11 @@ var QueryService = class {
|
|
|
3752
3642
|
}
|
|
3753
3643
|
const isCatalogHead = parsed.target === "note" && parsed.filters.some((f) => f.key === "type" && !f.negate && f.values.some((v) => v.value === "feed")) && (parsed.filters.some((f) => f.key === "source" && !f.negate && f.values.some((v) => v.value === "feed" || v.value === "feeds")) || parsed.sourceScope?.includes("feeds"));
|
|
3754
3644
|
if (isCatalogHead) {
|
|
3755
|
-
|
|
3756
|
-
this.staticNoteStore ? await this.staticNoteStore.getAllNotes() : []
|
|
3757
|
-
);
|
|
3758
|
-
return this.runFindCatalog(parsed, options2, notes2);
|
|
3645
|
+
return this.runFindCatalog(parsed, options2, await this.noteStore.getAllNotes());
|
|
3759
3646
|
}
|
|
3760
3647
|
const read = compileContentRead(parsed.filters, "note", parsed.sourceScope);
|
|
3761
|
-
const paging = domainPaging(parsed, options2, read.residual
|
|
3762
|
-
const fetchedNotes =
|
|
3648
|
+
const paging = domainPaging(parsed, options2, read.residual);
|
|
3649
|
+
const fetchedNotes = (read.filters.length > 0 || read.selection.length > 0 || paging.paged) && this.noteStore.queryDomain ? await this.noteStore.queryDomain({
|
|
3763
3650
|
plan: "notes",
|
|
3764
3651
|
selection: read.selection,
|
|
3765
3652
|
...read.filters.length ? { filters: read.filters } : {},
|
|
@@ -3771,11 +3658,6 @@ var QueryService = class {
|
|
|
3771
3658
|
let notes = domainNotes ? domainNotes.rows : await this.noteStore.getAllNotes();
|
|
3772
3659
|
const selectedFromDomain = domainNotes ? domainNotes.selectedCount : void 0;
|
|
3773
3660
|
const notesPaged = !!domainNotes && paging.paged;
|
|
3774
|
-
if (this.staticNoteStore) {
|
|
3775
|
-
const staticRows = applyNoteSelectionStages(await this.staticNoteStore.getAllNotes(), parsed);
|
|
3776
|
-
const known = new Set(notes.map((n) => n.id));
|
|
3777
|
-
notes = notes.concat(staticRows.filter((n) => !known.has(n.id)));
|
|
3778
|
-
}
|
|
3779
3661
|
notes = applyNoteSelectionStages(notes, parsed);
|
|
3780
3662
|
const selectedCount = selectedFromDomain ?? notes.length;
|
|
3781
3663
|
const ctx = runContext(options2);
|
|
@@ -3784,16 +3666,13 @@ var QueryService = class {
|
|
|
3784
3666
|
const matchingIds = /* @__PURE__ */ new Set();
|
|
3785
3667
|
for (const v of filter.values) {
|
|
3786
3668
|
const ids = await this.noteStore.getNoteIdsForTag(v.value);
|
|
3787
|
-
const sIds = this.staticNoteStore ? await this.staticNoteStore.getNoteIdsForTag(v.value) : /* @__PURE__ */ new Set();
|
|
3788
3669
|
ids.forEach((id) => matchingIds.add(id));
|
|
3789
|
-
sIds.forEach((id) => matchingIds.add(id));
|
|
3790
3670
|
}
|
|
3791
3671
|
notes = notes.filter((n) => matchingIds.has(n.id));
|
|
3792
3672
|
} else if (filter.key === "tags" && filter.negate) {
|
|
3793
3673
|
for (const v of filter.values) {
|
|
3794
3674
|
const ids = await this.noteStore.getNoteIdsForTag(v.value);
|
|
3795
|
-
|
|
3796
|
-
notes = notes.filter((n) => !ids.has(n.id) && !sIds.has(n.id));
|
|
3675
|
+
notes = notes.filter((n) => !ids.has(n.id));
|
|
3797
3676
|
}
|
|
3798
3677
|
} else if (filter.key === "effort" && !filter.negate) {
|
|
3799
3678
|
const matchingIds = /* @__PURE__ */ new Set();
|
|
@@ -3812,9 +3691,12 @@ var QueryService = class {
|
|
|
3812
3691
|
}
|
|
3813
3692
|
}
|
|
3814
3693
|
for (const filter of parsed.filters) {
|
|
3815
|
-
if (filter.key === "text"
|
|
3694
|
+
if (filter.key === "text") {
|
|
3816
3695
|
const search = filter.values.map((v) => v.value).join(" ").toLowerCase();
|
|
3817
|
-
notes = notes.filter((n) =>
|
|
3696
|
+
notes = notes.filter((n) => {
|
|
3697
|
+
const hit = n.title.toLowerCase().includes(search) || n.rawContent.toLowerCase().includes(search);
|
|
3698
|
+
return filter.negate ? !hit : hit;
|
|
3699
|
+
});
|
|
3818
3700
|
}
|
|
3819
3701
|
}
|
|
3820
3702
|
for (const filter of parsed.filters) {
|
|
@@ -3911,6 +3793,26 @@ var QueryService = class {
|
|
|
3911
3793
|
}
|
|
3912
3794
|
return containers;
|
|
3913
3795
|
}
|
|
3796
|
+
async hydrateBlocks(rows) {
|
|
3797
|
+
const ids = [...new Set(rows.map((row) => row.noteId))];
|
|
3798
|
+
if (ids.length === 0) return [];
|
|
3799
|
+
const notes = this.noteStore.getNotesByIds ? await this.noteStore.getNotesByIds(ids) : await this.noteStore.getAllNotes();
|
|
3800
|
+
const parents = /* @__PURE__ */ new Map();
|
|
3801
|
+
for (const note of notes) {
|
|
3802
|
+
if (!Number.isSafeInteger(note.sourceRevision) || note.sourceRevision < 1) continue;
|
|
3803
|
+
try {
|
|
3804
|
+
validateNoteBlocks(note.rawContent, note.blocks, note.sourceRevision);
|
|
3805
|
+
parents.set(note.id, note);
|
|
3806
|
+
} catch {
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
return rows.flatMap((row) => {
|
|
3810
|
+
const note = parents.get(row.noteId);
|
|
3811
|
+
const block = note?.blocks[row.blockId];
|
|
3812
|
+
if (!note || !block || row.id !== `${note.id}:${block.id}` || block.id !== row.blockId || block.kind !== row.dataType || block.version !== row.blockVersion || block.sourceRevision !== row.sourceRevision || note.sourceRevision !== row.sourceRevision || block.from !== row.from || block.to !== row.to) return [];
|
|
3813
|
+
return [{ ...row, rawContent: note.rawContent.slice(block.from, block.to) }];
|
|
3814
|
+
});
|
|
3815
|
+
}
|
|
3914
3816
|
/**
|
|
3915
3817
|
* Execute a :block query against the derived block_index store.
|
|
3916
3818
|
*/
|
|
@@ -3926,17 +3828,20 @@ var QueryService = class {
|
|
|
3926
3828
|
...paging.limit !== void 0 ? { limit: paging.limit } : {}
|
|
3927
3829
|
}) : void 0;
|
|
3928
3830
|
const domainBlocks = fetchedBlocks && fetchedBlocks.plan === "blocks" ? fetchedBlocks : void 0;
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
const
|
|
3831
|
+
const candidates = domainBlocks ? domainBlocks.rows : await this.blockStore.getAllBlocks();
|
|
3832
|
+
let blocks = await this.hydrateBlocks(candidates);
|
|
3833
|
+
const invalidCandidates = blocks.length !== candidates.length;
|
|
3834
|
+
const selectedFromDomain = domainBlocks && !invalidCandidates ? domainBlocks.selectedCount : void 0;
|
|
3835
|
+
const blocksPaged = !!domainBlocks && paging.paged && !invalidCandidates;
|
|
3836
|
+
if (domainBlocks && invalidCandidates) blocks = await this.hydrateBlocks(await this.blockStore.getAllBlocks());
|
|
3932
3837
|
blocks = applySourceFilter(blocks, parsed.filters);
|
|
3933
3838
|
blocks = blocks.filter((b) => !b.sourceId || WQL_SOURCE_VALUES.some((k) => sourceMatches(b, k)));
|
|
3934
3839
|
const selectedCount = selectedFromDomain ?? blocks.length;
|
|
3935
3840
|
const ctx = runContext(options2);
|
|
3936
3841
|
for (const filter of parsed.filters) {
|
|
3937
|
-
if (filter.key === "text"
|
|
3842
|
+
if (filter.key === "text") {
|
|
3938
3843
|
const search = filter.values.map((v) => v.value).join(" ").toLowerCase();
|
|
3939
|
-
blocks = blocks.filter((b) => b.rawContent.toLowerCase().includes(search));
|
|
3844
|
+
blocks = blocks.filter((b) => filter.negate !== b.rawContent.toLowerCase().includes(search));
|
|
3940
3845
|
}
|
|
3941
3846
|
}
|
|
3942
3847
|
for (const filter of parsed.filters) {
|
|
@@ -3961,18 +3866,16 @@ var QueryService = class {
|
|
|
3961
3866
|
const matchingNoteIds = /* @__PURE__ */ new Set();
|
|
3962
3867
|
for (const v of filter.values) {
|
|
3963
3868
|
const ids = await this.noteStore.getNoteIdsForTag(v.value);
|
|
3964
|
-
const sIds = this.staticNoteStore ? await this.staticNoteStore.getNoteIdsForTag(v.value) : /* @__PURE__ */ new Set();
|
|
3965
3869
|
ids.forEach((id) => matchingNoteIds.add(id));
|
|
3966
|
-
sIds.forEach((id) => matchingNoteIds.add(id));
|
|
3967
3870
|
}
|
|
3968
3871
|
blocks = blocks.filter((b) => matchingNoteIds.has(b.noteId));
|
|
3969
3872
|
} else if (filter.key === "effort" && !filter.negate) {
|
|
3970
3873
|
const matchingBlockIds = /* @__PURE__ */ new Set();
|
|
3971
3874
|
for (const v of filter.values) {
|
|
3972
3875
|
const rows = await this.blockEffortsStore.getAllFromIndex("by-effort", v.value);
|
|
3973
|
-
for (const
|
|
3876
|
+
for (const row of rows) matchingBlockIds.add(`${row.noteId}:${row.blockId}`);
|
|
3974
3877
|
}
|
|
3975
|
-
blocks = blocks.filter((
|
|
3878
|
+
blocks = blocks.filter((block) => matchingBlockIds.has(`${block.noteId}:${block.blockId}`));
|
|
3976
3879
|
}
|
|
3977
3880
|
}
|
|
3978
3881
|
for (const filter of parsed.filters) {
|
|
@@ -3982,11 +3885,7 @@ var QueryService = class {
|
|
|
3982
3885
|
}
|
|
3983
3886
|
}
|
|
3984
3887
|
if (parsed.window || options2.range) {
|
|
3985
|
-
|
|
3986
|
-
allNotes = allNotes.concat(await this.noteStore.getAllNotes());
|
|
3987
|
-
if (this.staticNoteStore) {
|
|
3988
|
-
allNotes = allNotes.concat(await this.staticNoteStore.getAllNotes());
|
|
3989
|
-
}
|
|
3888
|
+
const allNotes = await this.noteStore.getAllNotes();
|
|
3990
3889
|
const noteTimeMap = new Map(allNotes.map((n) => [n.id, n.date ?? n.createdAt]));
|
|
3991
3890
|
blocks = blocks.filter((b) => effectiveTimeWindow(noteTimeMap.get(b.noteId) ?? b.createdAt, parsed.window, options2.range, ctx));
|
|
3992
3891
|
}
|
|
@@ -4364,7 +4263,7 @@ var QueryService = class {
|
|
|
4364
4263
|
let values;
|
|
4365
4264
|
try {
|
|
4366
4265
|
values = members.map(
|
|
4367
|
-
(m) => shouldConvert && targetUnit ? convertViaCatalog(m.value, m.unit ?? m.metricUnit, targetUnit) : m.value
|
|
4266
|
+
(m) => shouldConvert && targetUnit && (m.unit ?? m.metricUnit) !== void 0 ? convertViaCatalog(m.value, m.unit ?? m.metricUnit, targetUnit) : m.value
|
|
4368
4267
|
);
|
|
4369
4268
|
} catch (e) {
|
|
4370
4269
|
error = e instanceof Error ? e.message : String(e);
|
|
@@ -4486,7 +4385,7 @@ var QueryService = class {
|
|
|
4486
4385
|
}
|
|
4487
4386
|
/** All content blocks — journal and seeded corpus in one store. */
|
|
4488
4387
|
async allContentBlocks() {
|
|
4489
|
-
return this.blockStore.getAllBlocks();
|
|
4388
|
+
return this.hydrateBlocks(await this.blockStore.getAllBlocks());
|
|
4490
4389
|
}
|
|
4491
4390
|
/** Map each note id to the wod blockContentIds it owns. */
|
|
4492
4391
|
async noteContentMap(noteIds) {
|
|
@@ -4563,7 +4462,10 @@ var QueryService = class {
|
|
|
4563
4462
|
type: "feed",
|
|
4564
4463
|
sourceId: `page:collection:${cat}`,
|
|
4565
4464
|
catalog: cat,
|
|
4566
|
-
createdAt: n.createdAt ?? 0
|
|
4465
|
+
createdAt: n.createdAt ?? 0,
|
|
4466
|
+
rawContent: "",
|
|
4467
|
+
sourceRevision: 1,
|
|
4468
|
+
blocks: {}
|
|
4567
4469
|
});
|
|
4568
4470
|
existingCatIds.add(cat);
|
|
4569
4471
|
}
|
|
@@ -4612,9 +4514,7 @@ var QueryService = class {
|
|
|
4612
4514
|
const matchingIds = /* @__PURE__ */ new Set();
|
|
4613
4515
|
for (const v of filter.values) {
|
|
4614
4516
|
const ids = await this.noteStore.getNoteIdsForTag(v.value);
|
|
4615
|
-
const sIds = this.staticNoteStore ? await this.staticNoteStore.getNoteIdsForTag(v.value) : /* @__PURE__ */ new Set();
|
|
4616
4517
|
ids.forEach((id) => matchingIds.add(id));
|
|
4617
|
-
sIds.forEach((id) => matchingIds.add(id));
|
|
4618
4518
|
}
|
|
4619
4519
|
matchingCatalogs = matchingCatalogs.filter((c) => {
|
|
4620
4520
|
const catId = catalogOfItem(c) ?? c.id;
|
|
@@ -4639,7 +4539,7 @@ var QueryService = class {
|
|
|
4639
4539
|
matchingCatalogs = matchingCatalogs.filter((c) => {
|
|
4640
4540
|
const catId = catalogOfItem(c) ?? c.id;
|
|
4641
4541
|
const members = membersByCat.get(catId) ?? [];
|
|
4642
|
-
const hit = members.some((m) => m.title.toLowerCase().includes(search));
|
|
4542
|
+
const hit = members.some((m) => m.title.toLowerCase().includes(search) || m.rawContent.toLowerCase().includes(search));
|
|
4643
4543
|
return filter.negate ? !hit : hit;
|
|
4644
4544
|
});
|
|
4645
4545
|
} else if (filter.key === "note") {
|
|
@@ -4679,56 +4579,6 @@ var QueryService = class {
|
|
|
4679
4579
|
}
|
|
4680
4580
|
};
|
|
4681
4581
|
|
|
4682
|
-
// src/static.ts
|
|
4683
|
-
function staticCatalogRoute(block) {
|
|
4684
|
-
const sourceId = block.sourceId;
|
|
4685
|
-
if (sourceId?.startsWith("page:collection:")) {
|
|
4686
|
-
const catalog = sourceId.slice("page:collection:".length);
|
|
4687
|
-
if (catalog) return { landing: true, catalog, sourceId };
|
|
4688
|
-
} else if (sourceId?.startsWith("collection:")) {
|
|
4689
|
-
const route = sourceId.slice("collection:".length);
|
|
4690
|
-
if (route) {
|
|
4691
|
-
const slash = route.indexOf("/");
|
|
4692
|
-
return slash === -1 ? { landing: true, catalog: route, sourceId: `page:collection:${route}` } : { landing: false, catalog: route.slice(0, slash), sourceId };
|
|
4693
|
-
}
|
|
4694
|
-
} else if (sourceId?.startsWith("feed:")) {
|
|
4695
|
-
const route = sourceId.slice("feed:".length);
|
|
4696
|
-
if (route) {
|
|
4697
|
-
const stem = route.startsWith("feeds/") ? route.slice("feeds/".length) : route;
|
|
4698
|
-
return { landing: false, catalog: stem.split("/")[0], sourceId };
|
|
4699
|
-
}
|
|
4700
|
-
}
|
|
4701
|
-
return { landing: false, catalog: catalogOfItem({ noteId: block.noteId, sourceId: block.sourceId }), sourceId };
|
|
4702
|
-
}
|
|
4703
|
-
function staticNotesFromBlocks(blocks) {
|
|
4704
|
-
const map = /* @__PURE__ */ new Map();
|
|
4705
|
-
for (const block of blocks) {
|
|
4706
|
-
if (map.has(block.noteId)) continue;
|
|
4707
|
-
const route = staticCatalogRoute(block);
|
|
4708
|
-
map.set(block.noteId, {
|
|
4709
|
-
id: block.noteId,
|
|
4710
|
-
title: block.noteTitle,
|
|
4711
|
-
createdAt: block.createdAt,
|
|
4712
|
-
type: route.landing ? "feed" : "note",
|
|
4713
|
-
sourceId: route.sourceId,
|
|
4714
|
-
catalog: route.catalog
|
|
4715
|
-
});
|
|
4716
|
-
}
|
|
4717
|
-
return Array.from(map.values());
|
|
4718
|
-
}
|
|
4719
|
-
function staticTagIndexFromBlocks(blocks) {
|
|
4720
|
-
const index = /* @__PURE__ */ new Map();
|
|
4721
|
-
for (const block of blocks) {
|
|
4722
|
-
if (block.dataType !== "frontmatter") continue;
|
|
4723
|
-
for (const tag of extractFrontmatterTags(block.rawContent)) {
|
|
4724
|
-
const ids = index.get(tag);
|
|
4725
|
-
if (ids) ids.add(block.noteId);
|
|
4726
|
-
else index.set(tag, /* @__PURE__ */ new Set([block.noteId]));
|
|
4727
|
-
}
|
|
4728
|
-
}
|
|
4729
|
-
return index;
|
|
4730
|
-
}
|
|
4731
|
-
|
|
4732
4582
|
// src/dashboard/model.ts
|
|
4733
4583
|
var DASHBOARD_WIDGET_TYPES = [
|
|
4734
4584
|
"table",
|
|
@@ -4917,6 +4767,117 @@ function buildDashboardDocument(sections, meta) {
|
|
|
4917
4767
|
};
|
|
4918
4768
|
}
|
|
4919
4769
|
|
|
4770
|
+
// src/dashboard/frontmatter.ts
|
|
4771
|
+
var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
4772
|
+
function unquote(value) {
|
|
4773
|
+
return value.replace(
|
|
4774
|
+
/^(['"])(.*)\1$/,
|
|
4775
|
+
(_match, quote, inner) => quote === '"' ? inner.replace(/\\(["\\])/g, "$1") : inner
|
|
4776
|
+
);
|
|
4777
|
+
}
|
|
4778
|
+
function parseFrontmatter(raw) {
|
|
4779
|
+
const match = raw.match(FRONTMATTER_RE);
|
|
4780
|
+
if (!match) return { meta: {}, body: raw };
|
|
4781
|
+
return { meta: parseMetaLines(match[1].split(/\r?\n/)), body: raw.slice(match[0].length) };
|
|
4782
|
+
}
|
|
4783
|
+
function parseMetaLines(lines) {
|
|
4784
|
+
const meta = {};
|
|
4785
|
+
for (let i = 0; i < lines.length; i++) {
|
|
4786
|
+
const keyMatch = lines[i].match(/^([A-Za-z][\w.-]*)\s*:(.*)$/);
|
|
4787
|
+
if (!keyMatch) continue;
|
|
4788
|
+
const key = keyMatch[1];
|
|
4789
|
+
const rawVal = keyMatch[2].trim();
|
|
4790
|
+
if (rawVal === "") {
|
|
4791
|
+
const items = [];
|
|
4792
|
+
while (i + 1 < lines.length) {
|
|
4793
|
+
const itemMatch = lines[i + 1].match(/^\s+-\s+(.+)$/);
|
|
4794
|
+
if (!itemMatch) break;
|
|
4795
|
+
items.push(itemMatch[1].trim());
|
|
4796
|
+
i++;
|
|
4797
|
+
}
|
|
4798
|
+
meta[key] = items.length > 0 ? items : "";
|
|
4799
|
+
} else {
|
|
4800
|
+
const wasQuoted = /^(['"])(.*)\1$/.test(rawVal);
|
|
4801
|
+
const value = unquote(rawVal);
|
|
4802
|
+
const num = Number(value);
|
|
4803
|
+
meta[key] = !wasQuoted && value !== "" && !isNaN(num) ? num : value;
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
return meta;
|
|
4807
|
+
}
|
|
4808
|
+
function parseFrontmatterBody(innerContent) {
|
|
4809
|
+
return parseMetaLines(innerContent.split(/\r?\n/));
|
|
4810
|
+
}
|
|
4811
|
+
function quoteYamlScalar(value) {
|
|
4812
|
+
if (value === "") return '""';
|
|
4813
|
+
const looksNumeric = !isNaN(Number(value));
|
|
4814
|
+
const looksKeyword = /^(true|false|null|yes|no|on|off)$/i.test(value);
|
|
4815
|
+
if (/[":'\n#{}[\\],&*?|<>=%!@`]/.test(value) || value !== value.trim() || value.startsWith("-") || looksNumeric || looksKeyword) {
|
|
4816
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
4817
|
+
}
|
|
4818
|
+
return value;
|
|
4819
|
+
}
|
|
4820
|
+
function serializeFrontmatter(meta) {
|
|
4821
|
+
const lines = [];
|
|
4822
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
4823
|
+
if (Array.isArray(value)) {
|
|
4824
|
+
if (value.length === 0) {
|
|
4825
|
+
lines.push(`${key}: ""`);
|
|
4826
|
+
continue;
|
|
4827
|
+
}
|
|
4828
|
+
lines.push(`${key}:`);
|
|
4829
|
+
for (const item of value) {
|
|
4830
|
+
lines.push(` - ${quoteYamlScalar(item)}`);
|
|
4831
|
+
}
|
|
4832
|
+
} else if (typeof value === "number") {
|
|
4833
|
+
lines.push(`${key}: ${value}`);
|
|
4834
|
+
} else {
|
|
4835
|
+
lines.push(`${key}: ${quoteYamlScalar(value)}`);
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
return lines.join("\n");
|
|
4839
|
+
}
|
|
4840
|
+
function stripFrontmatter(raw) {
|
|
4841
|
+
return parseFrontmatter(raw).body;
|
|
4842
|
+
}
|
|
4843
|
+
function getScalar(meta, key) {
|
|
4844
|
+
const value = meta[key];
|
|
4845
|
+
return typeof value === "string" || typeof value === "number" ? value : void 0;
|
|
4846
|
+
}
|
|
4847
|
+
function getList(meta, key) {
|
|
4848
|
+
const value = meta[key];
|
|
4849
|
+
return Array.isArray(value) ? value : [];
|
|
4850
|
+
}
|
|
4851
|
+
function parseFrontmatterCategories(raw) {
|
|
4852
|
+
return getList(parseFrontmatter(raw).meta, "category").map((c) => c.toLowerCase());
|
|
4853
|
+
}
|
|
4854
|
+
function extractFrontmatterTags(raw) {
|
|
4855
|
+
const meta = FRONTMATTER_RE.test(raw) ? parseFrontmatter(raw).meta : parseFrontmatterBody(raw);
|
|
4856
|
+
const tags = meta["tags"];
|
|
4857
|
+
const list = Array.isArray(tags) ? tags : typeof tags === "string" && tags.trim() ? tags.trim().startsWith("[") && tags.trim().endsWith("]") ? tags.trim().slice(1, -1).split(",") : [tags] : [];
|
|
4858
|
+
return [...new Set(list.map((tag) => tag.trim()).filter(Boolean))];
|
|
4859
|
+
}
|
|
4860
|
+
function parseFlatProperties(innerContent) {
|
|
4861
|
+
const props = {};
|
|
4862
|
+
for (const line of innerContent.split(/\r?\n/)) {
|
|
4863
|
+
const match = line.match(/^([^:]+):\s*(.*)$/);
|
|
4864
|
+
if (match) {
|
|
4865
|
+
props[match[1].trim()] = match[2].trim();
|
|
4866
|
+
}
|
|
4867
|
+
}
|
|
4868
|
+
return props;
|
|
4869
|
+
}
|
|
4870
|
+
function parseFrontmatterProps(lines) {
|
|
4871
|
+
const props = {};
|
|
4872
|
+
for (const line of lines) {
|
|
4873
|
+
const match = line.match(/^([^:]+):\s*(.*)$/);
|
|
4874
|
+
if (match) {
|
|
4875
|
+
props[match[1].trim()] = match[2].trim();
|
|
4876
|
+
}
|
|
4877
|
+
}
|
|
4878
|
+
return props;
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4920
4881
|
// src/dashboard/parser.ts
|
|
4921
4882
|
function parseDashboardNote(rawContent) {
|
|
4922
4883
|
const { meta } = parseFrontmatter(rawContent);
|
|
@@ -5121,6 +5082,44 @@ function appendWidget(raw, spec) {
|
|
|
5121
5082
|
while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
5122
5083
|
return [...lines, "", ...group, ""].join("\n");
|
|
5123
5084
|
}
|
|
5085
|
+
function widgetResult(raw, note, order) {
|
|
5086
|
+
let from = 0;
|
|
5087
|
+
while (from < raw.length && from < note.length && raw[from] === note[from]) from++;
|
|
5088
|
+
let to = raw.length;
|
|
5089
|
+
let nextTo = note.length;
|
|
5090
|
+
while (to > from && nextTo > from && raw[to - 1] === note[nextTo - 1]) {
|
|
5091
|
+
to--;
|
|
5092
|
+
nextTo--;
|
|
5093
|
+
}
|
|
5094
|
+
const queries = parseDashboardNote(raw).sections.filter((section) => section.type === "query");
|
|
5095
|
+
const nextQueries = parseDashboardNote(note).sections.filter((section) => section.type === "query");
|
|
5096
|
+
const oldOffsets = lineOffsets(raw);
|
|
5097
|
+
const nextOffsets = lineOffsets(note);
|
|
5098
|
+
const oldLines = raw.split("\n");
|
|
5099
|
+
const nextLines = note.split("\n");
|
|
5100
|
+
const retainedBlocks = [];
|
|
5101
|
+
for (const [nextIndex, oldIndex] of (order ?? queries.map((_, index) => index)).entries()) {
|
|
5102
|
+
if (oldIndex === null) continue;
|
|
5103
|
+
const block = queries[oldIndex];
|
|
5104
|
+
const next = nextQueries[nextIndex];
|
|
5105
|
+
if (!block || !next) throw new Error("Widget mutation lost its source lineage");
|
|
5106
|
+
retainedBlocks.push({
|
|
5107
|
+
from: oldOffsets[block.startLine],
|
|
5108
|
+
to: oldOffsets[block.endLine] + oldLines[block.endLine].replace(/\r$/, "").length,
|
|
5109
|
+
nextFrom: nextOffsets[next.startLine],
|
|
5110
|
+
nextTo: nextOffsets[next.endLine] + nextLines[next.endLine].replace(/\r$/, "").length
|
|
5111
|
+
});
|
|
5112
|
+
}
|
|
5113
|
+
return { ok: true, note, changes: raw === note ? [] : [{ from, to, insert: note.slice(from, nextTo) }], retainedBlocks };
|
|
5114
|
+
}
|
|
5115
|
+
function lineOffsets(raw) {
|
|
5116
|
+
let offset = 0;
|
|
5117
|
+
return raw.split("\n").map((line) => {
|
|
5118
|
+
const from = offset;
|
|
5119
|
+
offset += line.length + 1;
|
|
5120
|
+
return from;
|
|
5121
|
+
});
|
|
5122
|
+
}
|
|
5124
5123
|
function updateWidget(raw, key, expectedBody, spec) {
|
|
5125
5124
|
const { sections } = parseDashboardNote(raw);
|
|
5126
5125
|
const found = findWidgetGroup(sections, key, expectedBody);
|
|
@@ -5128,7 +5127,7 @@ function updateWidget(raw, key, expectedBody, spec) {
|
|
|
5128
5127
|
const { group } = found;
|
|
5129
5128
|
const lines = raw.split("\n");
|
|
5130
5129
|
lines.splice(group.startLine, group.endLine - group.startLine + 1, ...renderWidgetGroup(spec));
|
|
5131
|
-
return
|
|
5130
|
+
return widgetResult(raw, lines.join("\n"));
|
|
5132
5131
|
}
|
|
5133
5132
|
function duplicateWidget(raw, key, expectedBody) {
|
|
5134
5133
|
const { sections } = parseDashboardNote(raw);
|
|
@@ -5138,7 +5137,9 @@ function duplicateWidget(raw, key, expectedBody) {
|
|
|
5138
5137
|
const lines = raw.split("\n");
|
|
5139
5138
|
const copy = lines.slice(group.startLine, group.endLine + 1);
|
|
5140
5139
|
lines.splice(group.endLine + 1, 0, "", ...copy);
|
|
5141
|
-
|
|
5140
|
+
const order = sections.filter((section) => section.type === "query").map((_, index) => index);
|
|
5141
|
+
order.splice(group.widgetIndex + 1, 0, null);
|
|
5142
|
+
return widgetResult(raw, lines.join("\n"), order);
|
|
5142
5143
|
}
|
|
5143
5144
|
function removeWidget(raw, key, expectedBody) {
|
|
5144
5145
|
const { sections } = parseDashboardNote(raw);
|
|
@@ -5150,7 +5151,9 @@ function removeWidget(raw, key, expectedBody) {
|
|
|
5150
5151
|
if (group.startLine > 0 && group.startLine < lines.length && lines[group.startLine - 1] === "" && lines[group.startLine] === "") {
|
|
5151
5152
|
lines.splice(group.startLine, 1);
|
|
5152
5153
|
}
|
|
5153
|
-
|
|
5154
|
+
const order = sections.filter((section) => section.type === "query").map((_, index) => index);
|
|
5155
|
+
order.splice(group.widgetIndex, 1);
|
|
5156
|
+
return widgetResult(raw, lines.join("\n"), order);
|
|
5154
5157
|
}
|
|
5155
5158
|
function moveWidget(raw, key, expectedBody, delta) {
|
|
5156
5159
|
const { sections } = parseDashboardNote(raw);
|
|
@@ -5159,7 +5162,7 @@ function moveWidget(raw, key, expectedBody, delta) {
|
|
|
5159
5162
|
const { group } = found;
|
|
5160
5163
|
const groups = widgetGroupRanges(sections);
|
|
5161
5164
|
const neighbor = groups[group.widgetIndex + delta];
|
|
5162
|
-
if (!neighbor) return
|
|
5165
|
+
if (!neighbor) return widgetResult(raw, raw);
|
|
5163
5166
|
const lines = raw.split("\n");
|
|
5164
5167
|
const moving = lines.slice(group.startLine, group.endLine + 1);
|
|
5165
5168
|
if (delta === -1) {
|
|
@@ -5171,7 +5174,10 @@ function moveWidget(raw, key, expectedBody, delta) {
|
|
|
5171
5174
|
const insertAt = neighbor.endLine - shift + 1;
|
|
5172
5175
|
lines.splice(insertAt, 0, ...moving);
|
|
5173
5176
|
}
|
|
5174
|
-
|
|
5177
|
+
const order = groups.map((_, index) => index);
|
|
5178
|
+
order.splice(group.widgetIndex, 1);
|
|
5179
|
+
order.splice(group.widgetIndex + delta, 0, group.widgetIndex);
|
|
5180
|
+
return widgetResult(raw, lines.join("\n"), order);
|
|
5175
5181
|
}
|
|
5176
5182
|
function resizeWidget(raw, key, expectedBody, span) {
|
|
5177
5183
|
if (span.spanCols != null && (span.spanCols < 1 || span.spanCols > DASHBOARD_GRID_MAX_COLS)) {
|
|
@@ -5193,7 +5199,7 @@ function resizeWidget(raw, key, expectedBody, span) {
|
|
|
5193
5199
|
attributes: block.attributes,
|
|
5194
5200
|
attributeOrder: block.attributeOrder
|
|
5195
5201
|
});
|
|
5196
|
-
return
|
|
5202
|
+
return widgetResult(raw, lines.join("\n"));
|
|
5197
5203
|
}
|
|
5198
5204
|
function migrateLegacyDashboardBodies(raw) {
|
|
5199
5205
|
let out = raw;
|
|
@@ -5214,15 +5220,15 @@ ${query}
|
|
|
5214
5220
|
}
|
|
5215
5221
|
|
|
5216
5222
|
// src/version.ts
|
|
5217
|
-
var VERSION = "0.35.
|
|
5218
|
-
var GIT_SHA = "
|
|
5219
|
-
var BUILD_TIME = "2026-10-
|
|
5223
|
+
var VERSION = "0.35.2119";
|
|
5224
|
+
var GIT_SHA = "e0eb840";
|
|
5225
|
+
var BUILD_TIME = "2026-10-13T06:24:52.520Z";
|
|
5220
5226
|
var SEMVER = {
|
|
5221
|
-
version: "0.35.
|
|
5222
|
-
gitSha: "
|
|
5223
|
-
buildTime: "2026-10-
|
|
5227
|
+
version: "0.35.2119",
|
|
5228
|
+
gitSha: "e0eb840",
|
|
5229
|
+
buildTime: "2026-10-13T06:24:52.520Z"
|
|
5224
5230
|
};
|
|
5225
5231
|
|
|
5226
|
-
export { BUILD_TIME, CONTENT_GROUPING_DIMENSIONS, DASHBOARD_GRID_MAX_COLS, DASHBOARD_WIDGET_TYPES, DEFAULT_DASHBOARD_TITLE, DISCIPLINE_FACTORS, EFFORT_DISCIPLINES, GIT_SHA, PLANNED_WIDGET_TYPES, PageSourceRegistry, QueryDocumentRunner, QueryService, SEMVER, QueryDocumentRunner2 as SharedQueryDocumentRunner, UNASSIGNED, VERSION, WQL_AGGREGATORS, WQL_CALC_TARGETS, WQL_CHART_HEADS, WQL_COMPARISON_OPS, WQL_CONTENT_FILTER_KEYS, WQL_CONTENT_ONLY_KEYS, WQL_DISPLAY_UNITS, WQL_EFFORT_FILTER_KEYS, WQL_FIND_TARGETS, WQL_FUNCTION_HEADS, WQL_GRAINS, WQL_INTENSITY_TIERS, WQL_KEYWORDS, WQL_METRIC_AGGREGATES, WQL_METRIC_FAMILIES, WQL_NOTE_DEFAULT_SOURCES, WQL_RESULT_PLANES, WQL_ROLLUP_PERIODS, WQL_SOURCES, WQL_SOURCE_HEADS, WQL_SOURCE_HEAD_SCOPES, WQL_SOURCE_VALUES, WQL_STANDARD_DATASETS, WQL_TAG_KEYS, WQL_TYPED_TAG_KEYS, WQL_TYPE_HEADS, WQL_VIRTUAL_DIMS, allowedFilterTypesForTarget, appendSuffixes, appendWidget, buildDashboardDocument, buildDashboardScaffold, buildDrillDownQuery, captureContext, catalogOfItem, civilDateAdd, civilDateDiff, civilDateOf, civilDatesCoveredByRange, civilMonday, consumesRollupFacts, convertDisplay, createBuiltinFormulaEvaluator, dashboardSlug, defaultTokenValues, disciplineFactorFor, duplicateWidget, eventsToStoredLogs, extractDashboardTokens, extractFrontmatterTags, findTargetAdvisories, getList, getScalar, getUnitFamily, inRange, isAggregateQuery, isDashboardMeta, isDashboardWidgetType, isEffortDiscipline, isFindQuery, isPipelineQuery, isProposedMetric, migrateLegacyDashboardBodies, moveWidget, normalizeSummaryFacts, normalizeWql, parseDashboardNote, parseDocument, parseFlatProperties, parseFrontmatter, parseFrontmatterBody, parseFrontmatterCategories, parseFrontmatterProps, parseQuery, parseQueryWidgetSuffix, parseWqlSuffixes, projectEventToFacts, referencedTokens, removeWidget, renderWidgetGroup, resizeWidget, resolveCanonicalMetricKey, resolveOutputUnit, resolveWidgetType, resolveWindowRange, rowsParseError, serialize, serializeDocument, serializeFrontmatter, setDashboardTokenValue, sourceMatches, splitAtWhere,
|
|
5232
|
+
export { BUILD_TIME, CONTENT_GROUPING_DIMENSIONS, DASHBOARD_GRID_MAX_COLS, DASHBOARD_WIDGET_TYPES, DEFAULT_DASHBOARD_TITLE, DISCIPLINE_FACTORS, EFFORT_DISCIPLINES, GIT_SHA, PLANNED_WIDGET_TYPES, PageSourceRegistry, QueryDocumentRunner, QueryService, SEMVER, QueryDocumentRunner2 as SharedQueryDocumentRunner, UNASSIGNED, VERSION, WQL_AGGREGATORS, WQL_CALC_TARGETS, WQL_CHART_HEADS, WQL_COMPARISON_OPS, WQL_CONTENT_FILTER_KEYS, WQL_CONTENT_ONLY_KEYS, WQL_DISPLAY_UNITS, WQL_EFFORT_FILTER_KEYS, WQL_FIND_TARGETS, WQL_FUNCTION_HEADS, WQL_GRAINS, WQL_INTENSITY_TIERS, WQL_KEYWORDS, WQL_METRIC_AGGREGATES, WQL_METRIC_FAMILIES, WQL_NOTE_DEFAULT_SOURCES, WQL_RESULT_PLANES, WQL_ROLLUP_PERIODS, WQL_SOURCES, WQL_SOURCE_HEADS, WQL_SOURCE_HEAD_SCOPES, WQL_SOURCE_VALUES, WQL_STANDARD_DATASETS, WQL_TAG_KEYS, WQL_TYPED_TAG_KEYS, WQL_TYPE_HEADS, WQL_VIRTUAL_DIMS, allowedFilterTypesForTarget, appendSuffixes, appendWidget, buildDashboardDocument, buildDashboardScaffold, buildDrillDownQuery, captureContext, catalogOfItem, civilDateAdd, civilDateDiff, civilDateOf, civilDatesCoveredByRange, civilMonday, consumesRollupFacts, convertDisplay, createBuiltinFormulaEvaluator, dashboardSlug, defaultTokenValues, disciplineFactorFor, duplicateWidget, eventsToStoredLogs, extractDashboardTokens, extractFrontmatterTags, findTargetAdvisories, getList, getScalar, getUnitFamily, inRange, isAggregateQuery, isDashboardMeta, isDashboardWidgetType, isEffortDiscipline, isFindQuery, isPipelineQuery, isProposedMetric, migrateLegacyDashboardBodies, moveWidget, normalizeSummaryFacts, normalizeWql, parseDashboardNote, parseDocument, parseFlatProperties, parseFrontmatter, parseFrontmatterBody, parseFrontmatterCategories, parseFrontmatterProps, parseQuery, parseQueryWidgetSuffix, parseWqlSuffixes, projectEventToFacts, referencedTokens, removeWidget, renderWidgetGroup, resizeWidget, resolveCanonicalMetricKey, resolveOutputUnit, resolveWidgetType, resolveWindowRange, rowsParseError, serialize, serializeDocument, serializeFrontmatter, setDashboardTokenValue, sourceMatches, splitAtWhere, stripFrontmatter, substituteTokens2 as substituteTokens, substituteTokens as substituteTokensRaw, supportsWqlFilterKey, systemTimeZone, toEventRows, toSummaryEventRows, unknownTokensMessage, unknownWidgetTypeMessage, updateWidget, widgetBodyLine, widgetFenceTag, wql, wqlCompletion, wqlCompletionSource, wqlFilterKeys, wqlGroupingDimensions, wqlHighlightStyle, wqlLanguage, parser as wqlParser, wql_parser_terms_exports as wqlTerms, zonedNoon, zonedStartOfDay };
|
|
5227
5233
|
//# sourceMappingURL=index.mjs.map
|
|
5228
5234
|
//# sourceMappingURL=index.mjs.map
|