@burdenoff/be-sdk 2026.825.6 → 2026.825.7
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/{chunk-U4HHNEFE.js → chunk-WTEHAVBX.js} +15 -2
- package/dist/chunk-WTEHAVBX.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/metrics/index.d.ts +1 -0
- package/dist/metrics/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-U4HHNEFE.js.map +0 -1
|
@@ -8,6 +8,7 @@ var WorkspaceQuotaRegistry = class WorkspaceQuotaRegistry2 {
|
|
|
8
8
|
}
|
|
9
9
|
collectors = [];
|
|
10
10
|
gauges = /* @__PURE__ */ new Map();
|
|
11
|
+
previousWorkspaceIds = /* @__PURE__ */ new Map();
|
|
11
12
|
register(collector) {
|
|
12
13
|
this.collectors.push(collector);
|
|
13
14
|
}
|
|
@@ -24,12 +25,24 @@ var WorkspaceQuotaRegistry = class WorkspaceQuotaRegistry2 {
|
|
|
24
25
|
const gauge = this.gauges.get(collector.metricName);
|
|
25
26
|
if (!gauge) return;
|
|
26
27
|
const values = await collector.collect();
|
|
28
|
+
const currentWorkspaceIds = new Set(values.keys());
|
|
29
|
+
const labelSetKey = `${collector.metricName}\0${collector.quotaName}`;
|
|
30
|
+
const previousWorkspaceIds = this.previousWorkspaceIds.get(labelSetKey);
|
|
31
|
+
for (const workspaceId of previousWorkspaceIds ?? []) {
|
|
32
|
+
if (!currentWorkspaceIds.has(workspaceId)) {
|
|
33
|
+
gauge.set(0, {
|
|
34
|
+
workspace_id: workspaceId,
|
|
35
|
+
quota_name: collector.quotaName
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
27
39
|
for (const [workspaceId, value] of values) {
|
|
28
40
|
gauge.set(value, {
|
|
29
41
|
workspace_id: workspaceId,
|
|
30
42
|
quota_name: collector.quotaName
|
|
31
43
|
});
|
|
32
44
|
}
|
|
45
|
+
this.previousWorkspaceIds.set(labelSetKey, currentWorkspaceIds);
|
|
33
46
|
}));
|
|
34
47
|
}
|
|
35
48
|
/** Returns registered collectors — useful for activity-svc to discover tracked quota names. */
|
|
@@ -49,5 +62,5 @@ function resetWorkspaceQuotaRegistry() {
|
|
|
49
62
|
__name(resetWorkspaceQuotaRegistry, "resetWorkspaceQuotaRegistry");
|
|
50
63
|
|
|
51
64
|
export { getWorkspaceQuotaRegistry, resetWorkspaceQuotaRegistry };
|
|
52
|
-
//# sourceMappingURL=chunk-
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-WTEHAVBX.js.map
|
|
66
|
+
//# sourceMappingURL=chunk-WTEHAVBX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/metrics/workspace-quota-metrics.ts"],"names":["WorkspaceQuotaRegistry","collectors","gauges","Map","previousWorkspaceIds","register","collector","push","collectAll","Promise","allSettled","map","has","metricName","set","getMetricsRegistry","createGauge","help","gauge","get","values","collect","currentWorkspaceIds","Set","keys","labelSetKey","quotaName","workspaceId","workspace_id","quota_name","value","getCollectors","_registry","getWorkspaceQuotaRegistry","resetWorkspaceQuotaRegistry"],"mappings":";;;;AAkCA,IAAMA,sBAAAA,GAAN,MAAMA,uBAAAA,CAAAA;EAlCN;;;AAmCmBC,EAAAA,UAAAA,GAAwC,EAAA;AACxCC,EAAAA,MAAAA,uBAAaC,GAAAA,EAAAA;AACbC,EAAAA,oBAAAA,uBAA2BD,GAAAA,EAAAA;AAE5CE,EAAAA,QAAAA,CAASC,SAAAA,EAA0C;AACjD,IAAA,IAAA,CAAKL,UAAAA,CAAWM,KAAKD,SAAAA,CAAAA;AACvB,EAAA;;;;;;AAOA,EAAA,MAAME,UAAAA,GAA4B;AAChC,IAAA,MAAMC,QAAQC,UAAAA,CACZ,IAAA,CAAKT,UAAAA,CAAWU,GAAAA,CAAI,OAAOL,SAAAA,KAAAA;AACzB,MAAA,IAAI,CAAC,IAAA,CAAKJ,MAAAA,CAAOU,GAAAA,CAAIN,SAAAA,CAAUO,UAAU,CAAA,EAAG;AAC1C,QAAA,IAAA,CAAKX,MAAAA,CAAOY,GAAAA,CAAIR,SAAAA,CAAUO,UAAAA,EAAYE,kBAAAA,EAAAA,CAAqBC,WAAAA,CAAYV,SAAAA,CAAUO,UAAAA,EAAYP,SAAAA,CAAUW,IAAI,CAAA,CAAA;AAC7G,MAAA;AACA,MAAA,MAAMC,KAAAA,GAAQ,IAAA,CAAKhB,MAAAA,CAAOiB,GAAAA,CAAIb,UAAUO,UAAU,CAAA;AAClD,MAAA,IAAI,CAACK,KAAAA,EAAO;AACZ,MAAA,MAAME,MAAAA,GAAS,MAAMd,SAAAA,CAAUe,OAAAA,EAAO;AACtC,MAAA,MAAMC,mBAAAA,GAAsB,IAAIC,GAAAA,CAAIH,MAAAA,CAAOI,MAAI,CAAA;AAC/C,MAAA,MAAMC,cAAc,CAAA,EAAGnB,SAAAA,CAAUO,UAAU,CAAA,EAAA,EAAKP,UAAUoB,SAAS,CAAA,CAAA;AACnE,MAAA,MAAMtB,oBAAAA,GAAuB,IAAA,CAAKA,oBAAAA,CAAqBe,GAAAA,CAAIM,WAAAA,CAAAA;AAO3D,MAAA,KAAA,MAAWE,WAAAA,IAAevB,oBAAAA,IAAwB,EAAA,EAAI;AACpD,QAAA,IAAI,CAACkB,mBAAAA,CAAoBV,GAAAA,CAAIe,WAAAA,CAAAA,EAAc;AACzCT,UAAAA,KAAAA,CAAMJ,IAAI,CAAA,EAAG;YAAEc,YAAAA,EAAcD,WAAAA;AAAaE,YAAAA,UAAAA,EAAYvB,SAAAA,CAAUoB;WAAU,CAAA;AAC5E,QAAA;AACF,MAAA;AACA,MAAA,KAAA,MAAW,CAACC,WAAAA,EAAaG,KAAAA,CAAAA,IAAUV,MAAAA,EAAQ;AACzCF,QAAAA,KAAAA,CAAMJ,IAAIgB,KAAAA,EAAO;UAAEF,YAAAA,EAAcD,WAAAA;AAAaE,UAAAA,UAAAA,EAAYvB,SAAAA,CAAUoB;SAAU,CAAA;AAChF,MAAA;AACA,MAAA,IAAA,CAAKtB,oBAAAA,CAAqBU,GAAAA,CAAIW,WAAAA,EAAaH,mBAAAA,CAAAA;AAC7C,IAAA,CAAA,CAAA,CAAA;AAEJ,EAAA;;EAGAS,aAAAA,GAAoD;AAClD,IAAA,OAAO,IAAA,CAAK9B,UAAAA;AACd,EAAA;AACF,CAAA;AAEA,IAAI+B,SAAAA,GAA2C,IAAA;AAExC,SAASC,yBAAAA,GAAAA;AACd,EAAA,IAAI,CAACD,SAAAA,EAAWA,SAAAA,GAAY,IAAIhC,sBAAAA,EAAAA;AAChC,EAAA,OAAOgC,SAAAA;AACT;AAHgBC,MAAAA,CAAAA,yBAAAA,EAAAA,2BAAAA,CAAAA;AAMT,SAASC,2BAAAA,GAAAA;AACdF,EAAAA,SAAAA,GAAY,IAAA;AACd;AAFgBE,MAAAA,CAAAA,2BAAAA,EAAAA,6BAAAA,CAAAA","file":"chunk-WTEHAVBX.js","sourcesContent":["import { getMetricsRegistry } from '../instrumentation/metrics-collector.js';\nimport type { Gauge } from '../instrumentation/metrics-collector.js';\n\n/**\n * A single workspace-scoped quota metric.\n *\n * Services implement this and register it with WorkspaceQuotaRegistry at startup.\n * The metrics endpoint calls collectAll() on every scrape so values are always fresh.\n *\n * Pattern:\n * 1. Service registers collectors at startup (after instrumentation is initialized)\n * 2. /api/metrics handler calls collectAll() before serializing Prometheus output\n * 3. activity-svc scrapes /api/metrics and correlates values via quotaName to billing limits\n */\nexport interface WorkspaceQuotaCollector {\n /** Prometheus metric name, e.g. \"vibecontrols_tunnels_active\" */\n readonly metricName: string;\n /** Human-readable description shown in Prometheus HELP output */\n readonly help: string;\n /**\n * Billing quota name this metric maps to.\n * activity-svc uses this to correlate scraped values with quota limits.\n * e.g. \"vibecontrols.tunnels.active\"\n */\n readonly quotaName: string;\n /**\n * Called on every Prometheus scrape.\n * Must return current value per workspace ID.\n * Should be a fast, bounded DB query (GROUP BY workspace_id).\n * Failures are caught with Promise.allSettled — one failing collector does not block others.\n */\n collect(): Promise<Map<string, number>>;\n}\n\nclass WorkspaceQuotaRegistry {\n private readonly collectors: WorkspaceQuotaCollector[] = [];\n private readonly gauges = new Map<string, Gauge>();\n private readonly previousWorkspaceIds = new Map<string, Set<string>>();\n\n register(collector: WorkspaceQuotaCollector): void {\n this.collectors.push(collector);\n }\n\n /**\n * Runs all registered collectors and updates their gauges with fresh values.\n * Gauges are created lazily on first collectAll() to ensure MetricsRegistry\n * is initialized before gauge creation (instrumentation must be set up first).\n */\n async collectAll(): Promise<void> {\n await Promise.allSettled(\n this.collectors.map(async (collector) => {\n if (!this.gauges.has(collector.metricName)) {\n this.gauges.set(collector.metricName, getMetricsRegistry().createGauge(collector.metricName, collector.help));\n }\n const gauge = this.gauges.get(collector.metricName);\n if (!gauge) return;\n const values = await collector.collect();\n const currentWorkspaceIds = new Set(values.keys());\n const labelSetKey = `${collector.metricName}\\0${collector.quotaName}`;\n const previousWorkspaceIds = this.previousWorkspaceIds.get(labelSetKey);\n\n // Prometheus gauges retain every previously emitted label set. A GROUP BY\n // collector naturally omits a workspace once its value reaches zero, so\n // explicitly zero labels that disappeared from a successful collection.\n // Do not do this when collect() throws: Promise.allSettled preserves the\n // last known values until a later successful scrape can replace them.\n for (const workspaceId of previousWorkspaceIds ?? []) {\n if (!currentWorkspaceIds.has(workspaceId)) {\n gauge.set(0, { workspace_id: workspaceId, quota_name: collector.quotaName });\n }\n }\n for (const [workspaceId, value] of values) {\n gauge.set(value, { workspace_id: workspaceId, quota_name: collector.quotaName });\n }\n this.previousWorkspaceIds.set(labelSetKey, currentWorkspaceIds);\n })\n );\n }\n\n /** Returns registered collectors — useful for activity-svc to discover tracked quota names. */\n getCollectors(): readonly WorkspaceQuotaCollector[] {\n return this.collectors;\n }\n}\n\nlet _registry: WorkspaceQuotaRegistry | null = null;\n\nexport function getWorkspaceQuotaRegistry(): WorkspaceQuotaRegistry {\n if (!_registry) _registry = new WorkspaceQuotaRegistry();\n return _registry;\n}\n\n/** For testing only. */\nexport function resetWorkspaceQuotaRegistry(): void {\n _registry = null;\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -36,15 +36,15 @@ export { layer_exports as Layer } from './chunk-7UJXIX4I.js';
|
|
|
36
36
|
import './chunk-VFCMR5GX.js';
|
|
37
37
|
import { ContextManager } from './chunk-RZOFS2BQ.js';
|
|
38
38
|
export { ContextManager } from './chunk-RZOFS2BQ.js';
|
|
39
|
-
import { AuthModule } from './chunk-RXMOV3YE.js';
|
|
40
|
-
export { AuthModule } from './chunk-RXMOV3YE.js';
|
|
41
|
-
export { utils_exports as Utils } from './chunk-B7I4TABG.js';
|
|
42
39
|
export { cache_exports as Cache } from './chunk-AW6JUXCU.js';
|
|
43
40
|
import { disposeAll } from './chunk-VBXPFYZ5.js';
|
|
44
41
|
export { lifecycle_exports as Lifecycle, disposeAll, getRegisteredDisposableCount, registerDisposable, unregisterDisposable } from './chunk-VBXPFYZ5.js';
|
|
45
42
|
import './chunk-A5F6Z5UE.js';
|
|
46
|
-
|
|
43
|
+
import { AuthModule } from './chunk-RXMOV3YE.js';
|
|
44
|
+
export { AuthModule } from './chunk-RXMOV3YE.js';
|
|
45
|
+
export { utils_exports as Utils } from './chunk-B7I4TABG.js';
|
|
47
46
|
export { createInternalClient, createInternalClientForTenant, createInternalClientForWorkspaces } from './chunk-VI4VSNTI.js';
|
|
47
|
+
export { captcha_exports as Captcha, isCaptchaEnabled, verifyCaptcha, verifyCaptchaIfEnabled } from './chunk-YMZEUTD2.js';
|
|
48
48
|
export { crypto_exports as Crypto } from './chunk-SBS4S2PJ.js';
|
|
49
49
|
import { DatabaseModule } from './chunk-A6DGEZJ4.js';
|
|
50
50
|
export { DatabaseModule } from './chunk-A6DGEZJ4.js';
|
package/dist/metrics/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ interface WorkspaceQuotaCollector {
|
|
|
7
7
|
declare class WorkspaceQuotaRegistry {
|
|
8
8
|
private readonly collectors;
|
|
9
9
|
private readonly gauges;
|
|
10
|
+
private readonly previousWorkspaceIds;
|
|
10
11
|
register(collector: WorkspaceQuotaCollector): void;
|
|
11
12
|
collectAll(): Promise<void>;
|
|
12
13
|
getCollectors(): readonly WorkspaceQuotaCollector[];
|
package/dist/metrics/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { getWorkspaceQuotaRegistry, resetWorkspaceQuotaRegistry } from '../chunk-
|
|
1
|
+
export { getWorkspaceQuotaRegistry, resetWorkspaceQuotaRegistry } from '../chunk-WTEHAVBX.js';
|
|
2
2
|
import '../chunk-AWPNRV3L.js';
|
|
3
3
|
import '../chunk-XE4OXN2W.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHumanReadableErrorPlugin, formatHttpError, normalizeGraphQLResponse, createHttpErrorResponse } from '../chunk-OQLDXOZ3.js';
|
|
2
2
|
export { UserFacingGraphQLError, createHttpErrorResponse, createHumanReadableErrorPlugin, createWorkspaceGuardPlugin, formatHttpError, normalizeError, normalizeExecutionResultErrors, normalizeGraphQLResponse, normalizeGraphQLResponsePayload, toUserFacingGraphQLError } from '../chunk-OQLDXOZ3.js';
|
|
3
|
-
import { getWorkspaceQuotaRegistry } from '../chunk-
|
|
3
|
+
import { getWorkspaceQuotaRegistry } from '../chunk-WTEHAVBX.js';
|
|
4
4
|
import { setWorkspaceContext } from '../chunk-KESVEZB2.js';
|
|
5
5
|
import { I18n } from '../chunk-UJG32VIP.js';
|
|
6
6
|
import { getMetricsRegistry } from '../chunk-AWPNRV3L.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/be-sdk",
|
|
3
|
-
"version": "2026.825.
|
|
3
|
+
"version": "2026.825.7",
|
|
4
4
|
"description": "Backend SDK for Burdenoff products providing unified access to notifications, RBAC, activity tracking, usage monitoring, and more",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/metrics/workspace-quota-metrics.ts"],"names":["WorkspaceQuotaRegistry","collectors","gauges","Map","register","collector","push","collectAll","Promise","allSettled","map","has","metricName","set","getMetricsRegistry","createGauge","help","gauge","get","values","collect","workspaceId","value","workspace_id","quota_name","quotaName","getCollectors","_registry","getWorkspaceQuotaRegistry","resetWorkspaceQuotaRegistry"],"mappings":";;;;AAkCA,IAAMA,sBAAAA,GAAN,MAAMA,uBAAAA,CAAAA;EAlCN;;;AAmCmBC,EAAAA,UAAAA,GAAwC,EAAA;AACxCC,EAAAA,MAAAA,uBAAaC,GAAAA,EAAAA;AAE9BC,EAAAA,QAAAA,CAASC,SAAAA,EAA0C;AACjD,IAAA,IAAA,CAAKJ,UAAAA,CAAWK,KAAKD,SAAAA,CAAAA;AACvB,EAAA;;;;;;AAOA,EAAA,MAAME,UAAAA,GAA4B;AAChC,IAAA,MAAMC,QAAQC,UAAAA,CACZ,IAAA,CAAKR,UAAAA,CAAWS,GAAAA,CAAI,OAAOL,SAAAA,KAAAA;AACzB,MAAA,IAAI,CAAC,IAAA,CAAKH,MAAAA,CAAOS,GAAAA,CAAIN,SAAAA,CAAUO,UAAU,CAAA,EAAG;AAC1C,QAAA,IAAA,CAAKV,MAAAA,CAAOW,GAAAA,CAAIR,SAAAA,CAAUO,UAAAA,EAAYE,kBAAAA,EAAAA,CAAqBC,WAAAA,CAAYV,SAAAA,CAAUO,UAAAA,EAAYP,SAAAA,CAAUW,IAAI,CAAA,CAAA;AAC7G,MAAA;AACA,MAAA,MAAMC,KAAAA,GAAQ,IAAA,CAAKf,MAAAA,CAAOgB,GAAAA,CAAIb,UAAUO,UAAU,CAAA;AAClD,MAAA,IAAI,CAACK,KAAAA,EAAO;AACZ,MAAA,MAAME,MAAAA,GAAS,MAAMd,SAAAA,CAAUe,OAAAA,EAAO;AACtC,MAAA,KAAA,MAAW,CAACC,WAAAA,EAAaC,KAAAA,CAAAA,IAAUH,MAAAA,EAAQ;AACzCF,QAAAA,KAAAA,CAAMJ,IAAIS,KAAAA,EAAO;UAAEC,YAAAA,EAAcF,WAAAA;AAAaG,UAAAA,UAAAA,EAAYnB,SAAAA,CAAUoB;SAAU,CAAA;AAChF,MAAA;AACF,IAAA,CAAA,CAAA,CAAA;AAEJ,EAAA;;EAGAC,aAAAA,GAAoD;AAClD,IAAA,OAAO,IAAA,CAAKzB,UAAAA;AACd,EAAA;AACF,CAAA;AAEA,IAAI0B,SAAAA,GAA2C,IAAA;AAExC,SAASC,yBAAAA,GAAAA;AACd,EAAA,IAAI,CAACD,SAAAA,EAAWA,SAAAA,GAAY,IAAI3B,sBAAAA,EAAAA;AAChC,EAAA,OAAO2B,SAAAA;AACT;AAHgBC,MAAAA,CAAAA,yBAAAA,EAAAA,2BAAAA,CAAAA;AAMT,SAASC,2BAAAA,GAAAA;AACdF,EAAAA,SAAAA,GAAY,IAAA;AACd;AAFgBE,MAAAA,CAAAA,2BAAAA,EAAAA,6BAAAA,CAAAA","file":"chunk-U4HHNEFE.js","sourcesContent":["import { getMetricsRegistry } from '../instrumentation/metrics-collector.js';\nimport type { Gauge } from '../instrumentation/metrics-collector.js';\n\n/**\n * A single workspace-scoped quota metric.\n *\n * Services implement this and register it with WorkspaceQuotaRegistry at startup.\n * The metrics endpoint calls collectAll() on every scrape so values are always fresh.\n *\n * Pattern:\n * 1. Service registers collectors at startup (after instrumentation is initialized)\n * 2. /api/metrics handler calls collectAll() before serializing Prometheus output\n * 3. activity-svc scrapes /api/metrics and correlates values via quotaName to billing limits\n */\nexport interface WorkspaceQuotaCollector {\n /** Prometheus metric name, e.g. \"vibecontrols_tunnels_active\" */\n readonly metricName: string;\n /** Human-readable description shown in Prometheus HELP output */\n readonly help: string;\n /**\n * Billing quota name this metric maps to.\n * activity-svc uses this to correlate scraped values with quota limits.\n * e.g. \"vibecontrols.tunnels.active\"\n */\n readonly quotaName: string;\n /**\n * Called on every Prometheus scrape.\n * Must return current value per workspace ID.\n * Should be a fast, bounded DB query (GROUP BY workspace_id).\n * Failures are caught with Promise.allSettled — one failing collector does not block others.\n */\n collect(): Promise<Map<string, number>>;\n}\n\nclass WorkspaceQuotaRegistry {\n private readonly collectors: WorkspaceQuotaCollector[] = [];\n private readonly gauges = new Map<string, Gauge>();\n\n register(collector: WorkspaceQuotaCollector): void {\n this.collectors.push(collector);\n }\n\n /**\n * Runs all registered collectors and updates their gauges with fresh values.\n * Gauges are created lazily on first collectAll() to ensure MetricsRegistry\n * is initialized before gauge creation (instrumentation must be set up first).\n */\n async collectAll(): Promise<void> {\n await Promise.allSettled(\n this.collectors.map(async (collector) => {\n if (!this.gauges.has(collector.metricName)) {\n this.gauges.set(collector.metricName, getMetricsRegistry().createGauge(collector.metricName, collector.help));\n }\n const gauge = this.gauges.get(collector.metricName);\n if (!gauge) return;\n const values = await collector.collect();\n for (const [workspaceId, value] of values) {\n gauge.set(value, { workspace_id: workspaceId, quota_name: collector.quotaName });\n }\n })\n );\n }\n\n /** Returns registered collectors — useful for activity-svc to discover tracked quota names. */\n getCollectors(): readonly WorkspaceQuotaCollector[] {\n return this.collectors;\n }\n}\n\nlet _registry: WorkspaceQuotaRegistry | null = null;\n\nexport function getWorkspaceQuotaRegistry(): WorkspaceQuotaRegistry {\n if (!_registry) _registry = new WorkspaceQuotaRegistry();\n return _registry;\n}\n\n/** For testing only. */\nexport function resetWorkspaceQuotaRegistry(): void {\n _registry = null;\n}\n"]}
|