@x12i/memorix-service 3.8.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/analytics/definition.d.ts +158 -0
  2. package/dist/analytics/definition.d.ts.map +1 -0
  3. package/dist/analytics/definition.js +439 -0
  4. package/dist/analytics/definition.js.map +1 -0
  5. package/dist/analytics/engine.d.ts +63 -0
  6. package/dist/analytics/engine.d.ts.map +1 -0
  7. package/dist/analytics/engine.js +181 -0
  8. package/dist/analytics/engine.js.map +1 -0
  9. package/dist/analytics/host.d.ts +15 -0
  10. package/dist/analytics/host.d.ts.map +1 -0
  11. package/dist/analytics/host.js +129 -0
  12. package/dist/analytics/host.js.map +1 -0
  13. package/dist/analytics/materializer.d.ts +88 -0
  14. package/dist/analytics/materializer.d.ts.map +1 -0
  15. package/dist/analytics/materializer.js +358 -0
  16. package/dist/analytics/materializer.js.map +1 -0
  17. package/dist/analytics/pipeline-port.d.ts +10 -0
  18. package/dist/analytics/pipeline-port.d.ts.map +1 -0
  19. package/dist/analytics/pipeline-port.js +42 -0
  20. package/dist/analytics/pipeline-port.js.map +1 -0
  21. package/dist/analytics/projector.d.ts +60 -0
  22. package/dist/analytics/projector.d.ts.map +1 -0
  23. package/dist/analytics/projector.js +262 -0
  24. package/dist/analytics/projector.js.map +1 -0
  25. package/dist/analytics/state.d.ts +83 -0
  26. package/dist/analytics/state.d.ts.map +1 -0
  27. package/dist/analytics/state.js +273 -0
  28. package/dist/analytics/state.js.map +1 -0
  29. package/dist/analytics/tracker.d.ts +182 -0
  30. package/dist/analytics/tracker.d.ts.map +1 -0
  31. package/dist/analytics/tracker.js +1302 -0
  32. package/dist/analytics/tracker.js.map +1 -0
  33. package/dist/app.d.ts.map +1 -1
  34. package/dist/app.js +8 -0
  35. package/dist/app.js.map +1 -1
  36. package/dist/caller-identity.d.ts.map +1 -1
  37. package/dist/caller-identity.js +2 -0
  38. package/dist/caller-identity.js.map +1 -1
  39. package/dist/content-census-countex.d.ts +15 -0
  40. package/dist/content-census-countex.d.ts.map +1 -0
  41. package/dist/content-census-countex.js +18 -0
  42. package/dist/content-census-countex.js.map +1 -0
  43. package/dist/datasource-backfill.d.ts +39 -0
  44. package/dist/datasource-backfill.d.ts.map +1 -0
  45. package/dist/datasource-backfill.js +206 -0
  46. package/dist/datasource-backfill.js.map +1 -0
  47. package/dist/errors.d.ts.map +1 -1
  48. package/dist/errors.js +5 -0
  49. package/dist/errors.js.map +1 -1
  50. package/dist/index.d.ts +4 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +3 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/markdown-backfill.d.ts +23 -0
  55. package/dist/markdown-backfill.d.ts.map +1 -0
  56. package/dist/markdown-backfill.js +122 -0
  57. package/dist/markdown-backfill.js.map +1 -0
  58. package/dist/openapi/openapi.json +1151 -81
  59. package/dist/platform.d.ts +6 -0
  60. package/dist/platform.d.ts.map +1 -1
  61. package/dist/platform.js +55 -2
  62. package/dist/platform.js.map +1 -1
  63. package/dist/routes/analytics-counters.d.ts +8 -0
  64. package/dist/routes/analytics-counters.d.ts.map +1 -0
  65. package/dist/routes/analytics-counters.js +100 -0
  66. package/dist/routes/analytics-counters.js.map +1 -0
  67. package/dist/routes/data.d.ts.map +1 -1
  68. package/dist/routes/data.js +212 -3
  69. package/dist/routes/data.js.map +1 -1
  70. package/dist/routes/datasource-backfill.d.ts +4 -0
  71. package/dist/routes/datasource-backfill.d.ts.map +1 -0
  72. package/dist/routes/datasource-backfill.js +22 -0
  73. package/dist/routes/datasource-backfill.js.map +1 -0
  74. package/dist/routes/markdown-backfill.d.ts +4 -0
  75. package/dist/routes/markdown-backfill.d.ts.map +1 -0
  76. package/dist/routes/markdown-backfill.js +15 -0
  77. package/dist/routes/markdown-backfill.js.map +1 -0
  78. package/openapi/openapi.json +1151 -81
  79. package/package.json +5 -5
@@ -0,0 +1,63 @@
1
+ /**
2
+ * One Countex engine for every registered counter.
3
+ * Countex fixes maps at construction, so a single generic map carries all counters:
4
+ * the counter, its generation, and the covering pair live in the scope string.
5
+ */
6
+ import type { MongoClient } from "mongodb";
7
+ import { type CounterMap, type Countex, type DurableStorage } from "@x12i/countex";
8
+ export declare const ANALYTICS_COUNTER_ID = "memorix_analytics";
9
+ export declare const analyticsCounterMap: CounterMap;
10
+ export type CountexScopeParts = {
11
+ orgId: string;
12
+ counterId: string;
13
+ generation: number;
14
+ pair: [string, string] | null;
15
+ };
16
+ export declare function countexScope(parts: CountexScopeParts): string;
17
+ export declare function orgOfCountexScope(scope: string): string;
18
+ export type AnalyticsIncrement = {
19
+ scope: string;
20
+ at: string;
21
+ metric: string;
22
+ subject: string;
23
+ split?: string;
24
+ value?: number;
25
+ delta: number;
26
+ };
27
+ export type AnalyticsCell = {
28
+ metric: string;
29
+ subject: string;
30
+ split: string | null;
31
+ count: number;
32
+ sum: number;
33
+ };
34
+ export type AnalyticsCountex = {
35
+ readonly countex: Countex;
36
+ readonly storage: "memory" | "mongo";
37
+ ingest(increments: AnalyticsIncrement[]): Promise<void>;
38
+ flush(): Promise<void>;
39
+ /** All non-zero cells for a scope (timeframe `all`). */
40
+ readCells(scope: string): Promise<AnalyticsCell[]>;
41
+ /** Sum of counts per metric inside a window ending now. */
42
+ readWindow(scope: string, window: "24h" | "7d" | "30d", now: Date): Promise<Map<string, number>>;
43
+ /** Per-day counts for one metric over the last `days` days. */
44
+ readDaily(scope: string, metric: string, days: number, now: Date): Promise<Array<{
45
+ at: string;
46
+ value: number;
47
+ }>>;
48
+ shutdown(): Promise<void>;
49
+ };
50
+ export type CreateAnalyticsCountexOptions = {
51
+ mongoClient?: MongoClient | null;
52
+ /** Database holding the counter cells for an organization. */
53
+ dbNameFor?: (orgId: string) => string;
54
+ durable?: DurableStorage;
55
+ };
56
+ /**
57
+ * Countex trims and lowercases subject and metric dictionary keys. Bucket names are case
58
+ * sensitive, so keys are URI-encoded (no raw `^` survives) and upper-case letters escaped.
59
+ */
60
+ export declare function encodeKey(value: string): string;
61
+ export declare function decodeKey(value: string): string;
62
+ export declare function createAnalyticsCountex(opts?: CreateAnalyticsCountexOptions): Promise<AnalyticsCountex>;
63
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/analytics/engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AAIvB,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AAExD,eAAO,MAAM,mBAAmB,EAAE,UAiBjC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAS7D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC;IACrC,MAAM,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,wDAAwD;IACxD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnD,2DAA2D;IAC3D,UAAU,CACR,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,EAC5B,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChC,+DAA+D;IAC/D,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACjH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAgBD,wBAAsB,sBAAsB,CAC1C,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,gBAAgB,CAAC,CAuI3B"}
@@ -0,0 +1,181 @@
1
+ import { createCountex, } from "@x12i/countex";
2
+ import { MemoryCache, MemoryDurable } from "@x12i/countex/adapters/memory";
3
+ import { DurableReadCache } from "@x12i/countex/adapters/durable-cache";
4
+ export const ANALYTICS_COUNTER_ID = "memorix_analytics";
5
+ export const analyticsCounterMap = {
6
+ counterId: ANALYTICS_COUNTER_ID,
7
+ scope: { path: "$.scope" },
8
+ eventTime: { path: "$.at" },
9
+ subjects: [{ type: "s", path: "$.subject", required: true }],
10
+ metrics: [{ path: "$.metric", required: true }],
11
+ dimensions: [{ name: "split", path: "$.split" }],
12
+ measures: [{ name: "value", path: "$.value", aggregations: ["sum"], onMissing: "skip" }],
13
+ delta: { path: "$.delta", default: 1 },
14
+ timeframes: ["all", "hour", "day"],
15
+ options: { normalizeValues: false, skipMissingOptionalDimensions: true },
16
+ cardinality: {
17
+ maxDimensionValuesPerName: 10_000,
18
+ maxSubjectsPerScope: 500_000,
19
+ onLimit: "overflow",
20
+ overflowValue: "__OTHER__",
21
+ },
22
+ };
23
+ export function countexScope(parts) {
24
+ const pair = parts.pair
25
+ ? `${encodeURIComponent(parts.pair[0])}|${encodeURIComponent(parts.pair[1])}`
26
+ : "*";
27
+ return [
28
+ encodeURIComponent(parts.orgId),
29
+ `${encodeURIComponent(parts.counterId)}#${parts.generation}`,
30
+ pair,
31
+ ].join("|");
32
+ }
33
+ export function orgOfCountexScope(scope) {
34
+ return decodeURIComponent(scope.slice(0, scope.indexOf("|")));
35
+ }
36
+ /**
37
+ * Countex trims and lowercases subject and metric dictionary keys. Bucket names are case
38
+ * sensitive, so keys are URI-encoded (no raw `^` survives) and upper-case letters escaped.
39
+ */
40
+ export function encodeKey(value) {
41
+ return encodeURIComponent(value).replace(/[A-Z]/g, (c) => `^${c.toLowerCase()}`);
42
+ }
43
+ export function decodeKey(value) {
44
+ return decodeURIComponent(value.replace(/\^([a-z])/g, (_, c) => c.toUpperCase()));
45
+ }
46
+ function hourKey(d) {
47
+ return d.toISOString().slice(0, 13);
48
+ }
49
+ function dayKey(d) {
50
+ return d.toISOString().slice(0, 10);
51
+ }
52
+ function rowsOf(result) {
53
+ return result.rows.filter((r) => !!r && typeof r === "object" && "keys" in r && typeof r.count === "number");
54
+ }
55
+ export async function createAnalyticsCountex(opts = {}) {
56
+ let durable;
57
+ let storage = "memory";
58
+ if (opts.durable) {
59
+ durable = opts.durable;
60
+ }
61
+ else if (opts.mongoClient) {
62
+ const { MongoDurable } = await import("@x12i/countex/adapters/mongo");
63
+ const dbNameFor = opts.dbNameFor ?? ((orgId) => `${orgId}_operational`);
64
+ durable = new MongoDurable({
65
+ client: opts.mongoClient,
66
+ dbResolver: ({ scope }) => dbNameFor(orgOfCountexScope(scope)),
67
+ cellsCollection: "analytics_countex_cells",
68
+ dictCollection: "analytics_countex_dict",
69
+ seqCollection: "analytics_countex_seq",
70
+ });
71
+ storage = "mongo";
72
+ }
73
+ else {
74
+ durable = new MemoryDurable();
75
+ }
76
+ const countex = createCountex({
77
+ maps: [analyticsCounterMap],
78
+ durable,
79
+ cache: storage === "mongo" ? new DurableReadCache(durable) : new MemoryCache(),
80
+ flush: {
81
+ everyMs: 60_000,
82
+ maxBufferedCells: 200_000,
83
+ maxBufferedEvents: 100_000,
84
+ flushOnShutdown: true,
85
+ onOverflow: "block",
86
+ },
87
+ });
88
+ await countex.init();
89
+ const query = async (spec) => rowsOf(await countex.query({
90
+ counterId: ANALYTICS_COUNTER_ID,
91
+ format: "table",
92
+ resolveLabels: true,
93
+ ...spec,
94
+ }));
95
+ return {
96
+ countex,
97
+ storage,
98
+ async ingest(increments) {
99
+ if (increments.length === 0)
100
+ return;
101
+ await countex.ingestBatch(increments.map((i) => ({
102
+ scope: i.scope,
103
+ at: i.at,
104
+ metric: encodeKey(i.metric),
105
+ subject: encodeKey(i.subject),
106
+ ...(i.split !== undefined ? { split: i.split } : {}),
107
+ ...(i.value !== undefined ? { value: i.value * Math.sign(i.delta) } : {}),
108
+ delta: i.delta,
109
+ })));
110
+ },
111
+ async flush() {
112
+ await countex.flush();
113
+ },
114
+ async readCells(scope) {
115
+ const rows = await query({
116
+ scope,
117
+ timeframe: { type: "all", from: "all", to: "all" },
118
+ groupBy: ["metric", "subject", "dim:split"],
119
+ measures: ["value"],
120
+ });
121
+ const out = [];
122
+ for (const r of rows) {
123
+ if (r.count === 0 && !r.measures?.value?.sum)
124
+ continue;
125
+ const split = r.keys["dim:split"];
126
+ out.push({
127
+ metric: decodeKey(String(r.keys.metric)),
128
+ subject: decodeKey(String(r.keys.subject)),
129
+ split: split === undefined || split === null || split === "" ? null : String(split),
130
+ count: r.count,
131
+ sum: Number(r.measures?.value?.sum ?? 0),
132
+ });
133
+ }
134
+ return out;
135
+ },
136
+ async readWindow(scope, window, now) {
137
+ const hours = window === "24h" ? 24 : window === "7d" ? 7 * 24 : 30 * 24;
138
+ const from = new Date(now.getTime() - (hours - 1) * 3_600_000);
139
+ const rows = window === "24h"
140
+ ? await query({
141
+ scope,
142
+ timeframe: { type: "hour", from: hourKey(from), to: hourKey(now) },
143
+ groupBy: ["metric"],
144
+ })
145
+ : await query({
146
+ scope,
147
+ timeframe: {
148
+ type: "day",
149
+ from: dayKey(new Date(now.getTime() - (hours / 24 - 1) * 86_400_000)),
150
+ to: dayKey(now),
151
+ },
152
+ groupBy: ["metric"],
153
+ });
154
+ const out = new Map();
155
+ for (const r of rows) {
156
+ const metric = decodeKey(String(r.keys.metric));
157
+ out.set(metric, (out.get(metric) ?? 0) + r.count);
158
+ }
159
+ return out;
160
+ },
161
+ async readDaily(scope, metric, days, now) {
162
+ const rows = await query({
163
+ scope,
164
+ timeframe: {
165
+ type: "day",
166
+ from: dayKey(new Date(now.getTime() - (days - 1) * 86_400_000)),
167
+ to: dayKey(now),
168
+ },
169
+ groupBy: ["timeframeKey"],
170
+ metrics: [encodeKey(metric)],
171
+ });
172
+ return rows
173
+ .map((r) => ({ at: String(r.keys.timeframeKey), value: r.count }))
174
+ .sort((a, b) => a.at.localeCompare(b.at));
175
+ },
176
+ async shutdown() {
177
+ await countex.shutdown().catch(() => undefined);
178
+ },
179
+ };
180
+ }
181
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/analytics/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Platform adapters for the analytics tracker: metadata views, stored-head enumeration
3
+ * for the `@datasources` backfill, and cell cleanup on rebuild.
4
+ */
5
+ import type { MongoClient } from "mongodb";
6
+ import type { UnifiedMetadataClient } from "@x12i/memorix-metadata-runtime";
7
+ import { type AnalyticsMetadataView, type HeadSource } from "./tracker.js";
8
+ export declare function createAnalyticsMetadataViews(metadata: UnifiedMetadataClient): {
9
+ viewFor(agentIds: string[]): AnalyticsMetadataView;
10
+ invalidate(): void;
11
+ };
12
+ /** Pages current heads out of the org's content databases, in `_id` order per collection. */
13
+ export declare function createMongoHeadSource(client: MongoClient): HeadSource;
14
+ export declare function dropAnalyticsCells(client: MongoClient, dbName: string, scopePrefix: string): Promise<void>;
15
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/analytics/host.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAK5E,OAAO,EAAsB,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAQ/F,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qBAAqB,GAAG;IAC7E,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC;IACnD,UAAU,IAAI,IAAI,CAAC;CACpB,CA6DA;AAED,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CA4CrE;AAMD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhH"}
@@ -0,0 +1,129 @@
1
+ import { databaseNameFor } from "@x12i/memorix-data";
2
+ import { catalogFromMetadataClient } from "../catalog-bridge.js";
3
+ import { resolveObjectAndContentType } from "../data-changes.js";
4
+ import { isContentCollectionName } from "../datasource-backfill.js";
5
+ import { datasourceOfRecord } from "./tracker.js";
6
+ function asCategory(v) {
7
+ return v === "event" || v === "knowledge" ? v : "entity";
8
+ }
9
+ export function createAnalyticsMetadataViews(metadata) {
10
+ const cache = new Map();
11
+ const build = (agentIds) => {
12
+ const effective = metadata.resolveEffective(agentIds).effective ?? [];
13
+ const analytics = effective.filter((e) => e.kind === "analytics").map((e) => e.definition);
14
+ const abstractProps = new Map();
15
+ const objectTypes = new Map();
16
+ for (const e of effective) {
17
+ const def = e.definition;
18
+ if (e.kind === "abstract-types") {
19
+ const props = new Map();
20
+ for (const p of Array.isArray(def.properties) ? def.properties : []) {
21
+ const prop = p;
22
+ if (typeof prop.id !== "string")
23
+ continue;
24
+ props.set(prop.id, Array.isArray(prop.enum) ? { enum: prop.enum.filter((v) => typeof v === "string") } : {});
25
+ }
26
+ abstractProps.set(String(def.id ?? e.id), props);
27
+ }
28
+ else if (e.kind === "object-types") {
29
+ objectTypes.set(String(def.id ?? e.id), {
30
+ name: typeof def.name === "string" && def.name.trim() ? def.name : null,
31
+ dataCategory: asCategory(def.dataCategory),
32
+ });
33
+ }
34
+ }
35
+ const catalog = catalogFromMetadataClient(metadata, agentIds);
36
+ const members = new Map();
37
+ return {
38
+ analytics: () => analytics,
39
+ catalog: {
40
+ abstractProperties: (abstractType) => abstractProps.get(abstractType) ?? null,
41
+ hasObjectType: (objectType) => objectTypes.has(objectType),
42
+ },
43
+ members(abstractType) {
44
+ let list = members.get(abstractType);
45
+ if (!list) {
46
+ list = (catalog.getAbstractPlan?.(abstractType)?.members ?? []).map((m) => ({
47
+ objectType: m.objectType,
48
+ contentType: m.contentType,
49
+ }));
50
+ members.set(abstractType, list);
51
+ }
52
+ return list;
53
+ },
54
+ objectTypeName: (objectType) => objectTypes.get(objectType)?.name ?? null,
55
+ dataCategoryOf: (objectType) => objectTypes.get(objectType)?.dataCategory ?? "entity",
56
+ };
57
+ };
58
+ return {
59
+ viewFor(agentIds) {
60
+ const key = [...agentIds].sort().join(",");
61
+ let v = cache.get(key);
62
+ if (!v) {
63
+ v = build(agentIds);
64
+ cache.set(key, v);
65
+ }
66
+ return v;
67
+ },
68
+ invalidate() {
69
+ cache.clear();
70
+ },
71
+ };
72
+ }
73
+ /** Pages current heads out of the org's content databases, in `_id` order per collection. */
74
+ export function createMongoHeadSource(client) {
75
+ return {
76
+ async collections(orgId) {
77
+ let objectTypes = [];
78
+ try {
79
+ objectTypes = (await client.db(databaseNameFor(orgId, "operational")).collection("record-directory").distinct("objectType")).map(String);
80
+ }
81
+ catch {
82
+ objectTypes = [];
83
+ }
84
+ const out = [];
85
+ for (const category of ["entity", "event", "knowledge"]) {
86
+ const dbName = databaseNameFor(orgId, category);
87
+ const names = await client
88
+ .db(dbName)
89
+ .listCollections({}, { nameOnly: true })
90
+ .toArray()
91
+ .catch(() => []);
92
+ for (const { name } of names) {
93
+ if (!isContentCollectionName(name))
94
+ continue;
95
+ const { objectType, contentType } = resolveObjectAndContentType(name, objectTypes);
96
+ if (!contentType)
97
+ continue;
98
+ out.push({ key: `${dbName}/${name}`, objectType, contentType });
99
+ }
100
+ }
101
+ return out.sort((a, b) => a.key.localeCompare(b.key));
102
+ },
103
+ async page(_orgId, key, afterId, limit) {
104
+ const slash = key.indexOf("/");
105
+ const coll = client.db(key.slice(0, slash)).collection(key.slice(slash + 1));
106
+ const docs = await coll
107
+ .find(afterId === null ? {} : { _id: { $gt: afterId } })
108
+ .sort({ _id: 1 })
109
+ .limit(limit)
110
+ .project({ _id: 1, recordId: 1, "_system._datasource": 1 })
111
+ .toArray();
112
+ return docs.map((d) => ({
113
+ id: String(d._id),
114
+ recordId: String(d.recordId ?? d._id),
115
+ datasource: datasourceOfRecord(d),
116
+ }));
117
+ },
118
+ };
119
+ }
120
+ function escapeRegex(s) {
121
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
122
+ }
123
+ export async function dropAnalyticsCells(client, dbName, scopePrefix) {
124
+ const filter = { scopeId: { $regex: `^${escapeRegex(scopePrefix)}` } };
125
+ const db = client.db(dbName);
126
+ await db.collection("analytics_countex_cells").deleteMany(filter);
127
+ await db.collection("analytics_countex_dict").deleteMany(filter);
128
+ }
129
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/analytics/host.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAA+C,MAAM,cAAc,CAAC;AAI/F,SAAS,UAAU,CAAC,CAAU;IAC5B,OAAO,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,QAA+B;IAI1E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAiC,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,QAAkB,EAAyB,EAAE;QAC1D,MAAM,SAAS,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;QACtE,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAqB,CAAC,CAAC;QACtG,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4C,CAAC;QAC1E,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2D,CAAC;QACvF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,CAAC,CAAC,UAAqC,CAAC;YACpD,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA+B,CAAC;gBACrD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACpE,MAAM,IAAI,GAAG,CAAqC,CAAC;oBACnD,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;wBAAE,SAAS;oBAC1C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5H,CAAC;gBACD,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACnD,CAAC;iBAAM,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACrC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE;oBACtC,IAAI,EAAE,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;oBACvE,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC;iBAC3C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,IAAI,GAAG,EAA8D,CAAC;QACtF,OAAO;YACL,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS;YAC1B,OAAO,EAAE;gBACP,kBAAkB,EAAE,CAAC,YAAY,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI;gBAC7E,aAAa,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC;aAC3D;YACD,OAAO,CAAC,YAAY;gBAClB,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBACrC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,IAAI,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC1E,UAAU,EAAE,CAAC,CAAC,UAAU;wBACxB,WAAW,EAAE,CAAC,CAAC,WAAW;qBAC3B,CAAC,CAAC,CAAC;oBACJ,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;gBAClC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,IAAI,IAAI;YACzE,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,YAAY,IAAI,QAAQ;SACtF,CAAC;IACJ,CAAC,CAAC;IACF,OAAO;QACL,OAAO,CAAC,QAAQ;YACd,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,CAAC,CAAC,EAAE,CAAC;gBACP,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACpB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpB,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,UAAU;YACR,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,qBAAqB,CAAC,MAAmB;IACvD,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,KAAK;YACrB,IAAI,WAAW,GAAa,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,WAAW,GAAG,CACZ,MAAM,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,aAAsB,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CACtH,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,WAAW,GAAG,EAAE,CAAC;YACnB,CAAC;YACD,MAAM,GAAG,GAAoE,EAAE,CAAC;YAChF,KAAK,MAAM,QAAQ,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAU,EAAE,CAAC;gBACjE,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAChD,MAAM,KAAK,GAAG,MAAM,MAAM;qBACvB,EAAE,CAAC,MAAM,CAAC;qBACV,eAAe,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;qBACvC,OAAO,EAAE;qBACT,KAAK,CAAC,GAAG,EAAE,CAAC,EAA6B,CAAC,CAAC;gBAC9C,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;oBAC7B,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;wBAAE,SAAS;oBAC7C,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,2BAA2B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACnF,IAAI,CAAC,WAAW;wBAAE,SAAS;oBAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,IAAI,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;YACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK;YACpC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAkB,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9F,MAAM,IAAI,GAAG,MAAM,IAAI;iBACpB,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC;iBACvD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;iBAChB,KAAK,CAAC,KAAK,CAAC;iBACZ,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC;iBAC1D,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtB,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;gBACjB,QAAQ,EAAE,MAAM,CAAE,CAA4B,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;gBACjE,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC;aAClC,CAAC,CAAC,CAAC;QACN,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAmB,EAAE,MAAc,EAAE,WAAmB;IAC/F,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC;IACvE,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Pure shaping: Countex cells of one covering pair → the materialized analytics body.
3
+ * No storage access; the tracker supplies cells, windows, daily series, and leader rows.
4
+ */
5
+ import type { CounterDefinition } from "./definition.js";
6
+ import type { AnalyticsCell } from "./engine.js";
7
+ export type Metric = {
8
+ value: number | null;
9
+ produced: boolean;
10
+ };
11
+ export type Delta = {
12
+ current: number;
13
+ previous: number;
14
+ change: number;
15
+ produced: boolean;
16
+ };
17
+ export type TrendPoint = {
18
+ at: string;
19
+ scope?: Record<string, string>;
20
+ value: number;
21
+ };
22
+ export type Trend = {
23
+ key: string;
24
+ label: string;
25
+ window: "snapshots" | "7d" | "30d";
26
+ points: TrendPoint[];
27
+ };
28
+ export type LeaderRow = Record<string, unknown>;
29
+ export type GroupBlock = {
30
+ produced: boolean;
31
+ subject: string;
32
+ buckets: Record<string, Record<string, unknown>>;
33
+ };
34
+ export type PairSummary = {
35
+ measures: Record<string, Metric>;
36
+ groups: Record<string, Record<string, Metric> | GroupBlock>;
37
+ ratios: Record<string, Metric>;
38
+ derived: Record<string, Metric>;
39
+ splits: Record<string, Record<string, Record<string, Metric>>>;
40
+ unwinds: Record<string, Array<Record<string, unknown>>>;
41
+ coverage: Array<{
42
+ stepId: string;
43
+ present: number;
44
+ expected: number;
45
+ produced: boolean;
46
+ }>;
47
+ transitions: Record<string, Array<{
48
+ from: unknown;
49
+ to: unknown;
50
+ count: number;
51
+ }>>;
52
+ presence: Record<string, number>;
53
+ };
54
+ /** Ids ranked by how many counted subjects reference them (ties by id). */
55
+ export declare function topLeaderIds(cells: AnalyticsCell[], leaderKey: string, limit: number): Array<{
56
+ id: string;
57
+ count: number;
58
+ }>;
59
+ export declare function summarizePair(def: CounterDefinition, cells: AnalyticsCell[], opts: {
60
+ live: boolean;
61
+ organizationWide: boolean;
62
+ }): PairSummary;
63
+ export declare function scopeValuesOf(def: CounterDefinition, pair: [string, string] | null): Record<string, string>;
64
+ export declare function hasScopePlaceholder(def: CounterDefinition, template: string): boolean;
65
+ export declare function resolveRecordIds(def: CounterDefinition, pair: [string, string] | null): {
66
+ current: string;
67
+ history: string | null;
68
+ };
69
+ export type EnvelopeInput = {
70
+ definition: CounterDefinition;
71
+ counter: {
72
+ id: string;
73
+ generation: number;
74
+ status: string;
75
+ hash: string;
76
+ origin: string;
77
+ };
78
+ generatedAt: string;
79
+ pair: [string, string] | null;
80
+ current: PairSummary;
81
+ previous: PairSummary | null;
82
+ /** Per window, the count of each metric whose event time falls inside it. */
83
+ windows: Partial<Record<"24h" | "7d" | "30d", Map<string, number>>>;
84
+ trends: Trend[];
85
+ leaders: Record<string, LeaderRow[]>;
86
+ };
87
+ export declare function buildEnvelope(input: EnvelopeInput): Record<string, unknown>;
88
+ //# sourceMappingURL=materializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materializer.d.ts","sourceRoot":"","sources":["../../src/analytics/materializer.ts"],"names":[],"mappings":"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"}