@friggframework/core 2.0.0--canary.622.eb2c9bd.0 → 2.0.0--canary.622.faffe5f.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.
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Usage Commands
3
3
  *
4
- * Application Layer — the read/write surface over the durable usage store
5
- * (ADR-011 §5). Exposed as `frigg.usage.*` on the unified command object so
4
+ * Application Layer — the read/write surface over the durable usage store.
5
+ * Exposed as `frigg.usage.*` on the unified command object so
6
6
  * reports and integration code query usage without touching the repository.
7
7
  *
8
8
  * @example
@@ -33,7 +33,8 @@ function createUsageCommands({ usageRepository, northStar = null } = {}) {
33
33
  value = 1,
34
34
  at = new Date(),
35
35
  }) {
36
- for (const window of computeUsageWindows(at)) {
36
+ const windows = computeUsageWindows(at);
37
+ for (const window of windows) {
37
38
  await repository.increment({
38
39
  integrationId,
39
40
  integrationType,
@@ -53,7 +54,7 @@ function createUsageCommands({ usageRepository, northStar = null } = {}) {
53
54
  },
54
55
 
55
56
  /**
56
- * First-class North Star read (ADR-011 Decision 5). Resolves the
57
+ * First-class North Star read. Resolves the
57
58
  * configured counter for an integration type (byType wins over default),
58
59
  * then returns its totals from the durable usage store. Returns `null`
59
60
  * when no North Star is configured, so callers can branch without
@@ -19,7 +19,7 @@ const { createUsageCommands } = require('./commands/usage-commands');
19
19
  * @param {Object} params.integrationClass - Integration class (required)
20
20
  * @param {Object} [params.northStar] - Resolved North Star config
21
21
  * (`Definition.telemetry.northStar`) so `frigg.usage.northStar(...)` can read
22
- * it (ADR-011 Decision 5). Injected by the caller that owns the app definition
22
+ * it. Injected by the caller that owns the app definition
23
23
  * (the handler/report runner) — the application layer never reaches up to load
24
24
  * it. Omitted → usage reads report no North Star.
25
25
  * @returns {Object} Unified commands object with all CRUD operations
@@ -57,7 +57,7 @@ function createFriggCommands({ integrationClass, northStar = null }) {
57
57
  // Process commands
58
58
  ...processCommands,
59
59
 
60
- // Usage read/write (ADR-011) — nested to match `frigg.usage.*`.
60
+ // Usage read/write — nested to match `frigg.usage.*`.
61
61
  // northStar injected by the caller (composition root), not loaded here.
62
62
  usage: createUsageCommands({ northStar }),
63
63
  };
@@ -153,8 +153,8 @@ const createHandler = (optionByName = {}) => {
153
153
  ? usageRollup
154
154
  : getUsageRollupSubscriber();
155
155
 
156
- // Wire adopter-declared telemetry subscribers once per cold start
157
- // (ADR-011 Decision 6). Memoized in the singleton, so this is a cheap
156
+ // Wire adopter-declared telemetry subscribers once per cold start.
157
+ // Memoized in the singleton, so this is a cheap
158
158
  // no-op after the first invocation.
159
159
  getPluginTelemetrySubscribers();
160
160
 
@@ -25,7 +25,7 @@ class IntegrationEventDispatcher {
25
25
  }
26
26
 
27
27
  /**
28
- * Resolve + invoke a handler, auto-instrumented (ADR-011 Decision 2). This
28
+ * Resolve + invoke a handler, auto-instrumented. This
29
29
  * is the seam for queue/webhook/defined-route dispatch; the `this.on` path
30
30
  * (user actions, lifecycle) is instrumented in IntegrationBase.send().
31
31
  */
package/index.js CHANGED
@@ -143,7 +143,7 @@ module.exports = {
143
143
  createReportingRouter,
144
144
  createReportingRepository,
145
145
 
146
- // telemetry (ADR-011)
146
+ // telemetry
147
147
  createTelemetry,
148
148
  getTelemetry,
149
149
  createUsageRepository,
@@ -79,7 +79,7 @@ class IntegrationBase {
79
79
  // Tier 3 Integration Extensions — see packages/core/integrations/EXTENSIONS.md
80
80
  // Shape: { [bindingName]: { extension, handlers?: { [eventName]: methodName } } }
81
81
  extensions: {},
82
- // Usage-counter opt-in (ADR-011). Declaring a canonical key opts into the
82
+ // Usage-counter opt-in. Declaring a canonical key opts into the
83
83
  // cross-integration comparison report + durable rollup; custom keys are
84
84
  // comparable within this integration type. Shape:
85
85
  // usage: { canonical: ['records.synced', ...], custom: { 'deals.enriched': { unit, label } } }
@@ -108,7 +108,7 @@ class IntegrationBase {
108
108
  this.messages = { errors: [], warnings: [] };
109
109
  this._isHydrated = false;
110
110
 
111
- // Telemetry (ADR-011): every instance carries the service so integration
111
+ // Telemetry: every instance carries the service so integration
112
112
  // code can call `this.telemetry.*`. Extracted before the record check so
113
113
  // passing only `telemetry` never triggers a hollow hydration. Bound to
114
114
  // this instance so emissions auto-carry `integration_type` for the usage
@@ -223,7 +223,7 @@ class IntegrationBase {
223
223
 
224
224
  this._isHydrated = Boolean(this.id);
225
225
 
226
- // ADR-011 Decision 2: log the instance-open exactly once per hydrated
226
+ // Log the instance-open exactly once per hydrated
227
227
  // instance, carrying the standard identifier set — so an integration is
228
228
  // visible in telemetry even on a path that never dispatches a handler.
229
229
  // High-cardinality ids ride the bus context (3rd arg), never metric
@@ -249,7 +249,7 @@ class IntegrationBase {
249
249
  }
250
250
 
251
251
  /**
252
- * Standard telemetry identifier set (ADR-011 Decision 3). Assembled from the
252
+ * Standard telemetry identifier set. Assembled from the
253
253
  * hydrated record (integrationId, userId, version), the static Definition
254
254
  * (integrationType, version fallback), and the environment (stage, appName).
255
255
  * High-cardinality ids (integrationId, userId) ride span baggage only — never
@@ -812,7 +812,7 @@ class IntegrationBase {
812
812
  `Event ${event} is not defined in the Integration event object`
813
813
  );
814
814
  }
815
- // Auto-instrument (ADR-011 Decision 2). This is the seam for user
815
+ // Auto-instrument. This is the seam for user
816
816
  // actions, config-options, and lifecycle events dispatched via `this.on`
817
817
  // (the queue/webhook/route paths go through IntegrationEventDispatcher).
818
818
  return instrumentHandler(
@@ -44,7 +44,7 @@ class Requester extends Delegate {
44
44
  // Instance methods can use this.fetch without differentiating
45
45
  this.fetch = get(params, 'fetch', fetch);
46
46
 
47
- // Telemetry (ADR-011). Defaults to the process singleton; overridable
47
+ // Telemetry. Defaults to the process singleton; overridable
48
48
  // for tests. Outbound requests are instrumented in `_request`.
49
49
  //
50
50
  // Attribution boundary: the `frigg.apimodule.requests` OTel metric fires
@@ -103,7 +103,7 @@ class Requester extends Delegate {
103
103
  };
104
104
 
105
105
  /**
106
- * Instrumenting entry point (ADR-011 P7). Wraps the whole logical request —
106
+ * Instrumenting entry point. Wraps the whole logical request —
107
107
  * including retry/refresh recursion — in a single span + one
108
108
  * `frigg.apimodule.requests` counter, emitted on the `i === 0` boundary so
109
109
  * retries are never double-counted. The full URL rides the span only; the
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.622.eb2c9bd.0",
4
+ "version": "2.0.0--canary.622.faffe5f.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-apigatewaymanagementapi": "^3.588.0",
7
7
  "@aws-sdk/client-kms": "^3.588.0",
@@ -45,9 +45,9 @@
45
45
  }
46
46
  },
47
47
  "devDependencies": {
48
- "@friggframework/eslint-config": "2.0.0--canary.622.eb2c9bd.0",
49
- "@friggframework/prettier-config": "2.0.0--canary.622.eb2c9bd.0",
50
- "@friggframework/test": "2.0.0--canary.622.eb2c9bd.0",
48
+ "@friggframework/eslint-config": "2.0.0--canary.622.faffe5f.0",
49
+ "@friggframework/prettier-config": "2.0.0--canary.622.faffe5f.0",
50
+ "@friggframework/test": "2.0.0--canary.622.faffe5f.0",
51
51
  "@prisma/client": "^6.19.3",
52
52
  "@types/lodash": "4.17.15",
53
53
  "@typescript-eslint/eslint-plugin": "^8.0.0",
@@ -87,5 +87,5 @@
87
87
  "publishConfig": {
88
88
  "access": "public"
89
89
  },
90
- "gitHead": "eb2c9bde95b23f2f854fd5d78b2c5388ac5222d8"
90
+ "gitHead": "faffe5ff8b3fea6bbb46a52502cbd5b5ecb35559"
91
91
  }
@@ -40,7 +40,7 @@ function buildTypeLabels() {
40
40
 
41
41
  function createReportingRouter() {
42
42
  const reportingRepository = createReportingRepository();
43
- // ADR-011 hand-off: enrich the report with feature-usage columns read from
43
+ // Enrich the report with feature-usage columns read from
44
44
  // the Frigg-owned usage store. Best-effort — a failure to construct it never
45
45
  // blocks the structural report.
46
46
  let usageRepository = null;
@@ -26,7 +26,7 @@ class ListIntegrationsReport {
26
26
  throw new Error('reportingRepository is required');
27
27
  }
28
28
  this.reportingRepository = reportingRepository;
29
- // Optional ADR-011 usage store (the ADR-010 hand-off). When present, the
29
+ // Optional usage store (the ADR-010 hand-off). When present, the
30
30
  // report's byType buckets are enriched with feature-usage columns read
31
31
  // ONLY from this store — never an external APM.
32
32
  this.usageRepository = usageRepository || null;
@@ -87,7 +87,7 @@ class ListIntegrationsReport {
87
87
  bucket.byStatus[statusKey] = (bucket.byStatus[statusKey] ?? 0) + 1;
88
88
  }
89
89
 
90
- // Additive usage columns (ADR-011). Read per-type totals for each
90
+ // Additive usage columns. Read per-type totals for each
91
91
  // canonical counter; a type with no rows reads as 0. Guarded so a usage
92
92
  // store failure never breaks the structural report.
93
93
  if (this.usageRepository) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Wrap a telemetry service so an integration instance's emissions automatically
3
- * carry its `integration_type` (ADR-011). This lets developers write
3
+ * carry its `integration_type`. This lets developers write
4
4
  * `this.telemetry.count('records.synced', n, { entity })` with no per-call
5
5
  * boilerplate, while the usage rollup still attributes the counter to the right
6
6
  * integration type.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Canonical usage-counter vocabulary (ADR-011 Usage-Counter Contract §1).
2
+ * Canonical usage-counter vocabulary.
3
3
  *
4
4
  * These core-owned, versioned keys are the ONLY metrics guaranteed comparable
5
5
  * *across* integration types — they power ADR-010's apples-to-apples comparison
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Builds OpenTelemetry span/metric exporters from an app-definition descriptor
3
- * (ADR-011 Decision 1). All OTel packages are lazy-`require`d here so the no-op
2
+ * Builds OpenTelemetry span/metric exporters from an app-definition descriptor.
3
+ * All OTel packages are lazy-`require`d here so the no-op
4
4
  * path (which never calls this) loads zero OTel modules.
5
5
  *
6
6
  * Supported descriptor `type`s:
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Wraps a single integration handler invocation with a span + the
3
- * `frigg.handler.invocations` counter (ADR-011 Decision 2). Shared by the two
3
+ * `frigg.handler.invocations` counter. Shared by the two
4
4
  * dispatch seams — `IntegrationBase.send()` and `IntegrationEventDispatcher` —
5
5
  * so both paths are instrumented identically.
6
6
  *
@@ -8,7 +8,7 @@ const {
8
8
  * No-op telemetry implementation.
9
9
  *
10
10
  * This is the default when no OTel exporter is configured, so telemetry "rides
11
- * for free" (ADR-011): integration code can call `this.telemetry.*`
11
+ * for free": integration code can call `this.telemetry.*`
12
12
  * unconditionally and it costs nothing on the OTel side. Critically, this module
13
13
  * imports **zero** OpenTelemetry packages — the no-op path never loads the OTel
14
14
  * SDK (guarded by a require-graph test), protecting Lambda cold-start.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Adopter North Star metric (ADR-011 Decision 5). A North Star simply references
2
+ * Adopter North Star metric. A North Star simply references
3
3
  * a usage-counter key (canonical or custom); its value is then read like any
4
4
  * other counter via `frigg.usage.totals({ metric: northStarKey })`. It is
5
5
  * populated either by (a) direct emission of that counter, or (b) derived from a
@@ -47,7 +47,7 @@ function ensureContextManager() {
47
47
  }
48
48
 
49
49
  /**
50
- * The OpenTelemetry-backed telemetry service (ADR-011 Decision 1). Reached only
50
+ * The OpenTelemetry-backed telemetry service. Reached only
51
51
  * when a real exporter is configured; `createTelemetry` returns the no-op
52
52
  * otherwise. `BatchSpanProcessor` is used uniformly — spans are delivered by the
53
53
  * bounded `forceFlush()` the Lambda handler awaits before the container freezes
@@ -1,8 +1,8 @@
1
1
  const { wireTelemetrySubscribers } = require('./plugin-subscribers');
2
2
 
3
3
  /**
4
- * Process-wide wiring of adopter-declared telemetry subscribers (ADR-011
5
- * Decision 6). Built once per cold start and reused for the life of the Lambda
4
+ * Process-wide wiring of adopter-declared telemetry subscribers. Built once per
5
+ * cold start and reused for the life of the Lambda
6
6
  * container, mirroring the usage-rollup singleton. Independent of the usage
7
7
  * rollup: adopter taps wire even when no integration declares `Definition.usage`.
8
8
  * Never throws — a bad/absent app definition just means no adopter taps.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Declarative plugin/extension telemetry taps (ADR-011 Decision 6).
2
+ * Declarative plugin/extension telemetry taps.
3
3
  *
4
4
  * The built-in usage rollup and North Star derivation subscribe to the telemetry
5
5
  * bus in framework code; this lets an ADOPTER subscribe declaratively from the
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Resolves and validates the telemetry section of an app definition
3
- * (ADR-011 Decisions 1 & 5) into a normalized config the TelemetryService and
3
+ * into a normalized config the TelemetryService and
4
4
  * usage rollup consume: `{ exporter, northStar, sampleRatio }`.
5
5
  *
6
6
  * Exporter default is keyed off STAGE: only a genuinely LOCAL run (STAGE=local)
@@ -1,7 +1,7 @@
1
1
  const { AsyncLocalStorage } = require('node:async_hooks');
2
2
 
3
3
  /**
4
- * Ambient telemetry context (ADR-011). A single process-wide AsyncLocalStorage
4
+ * Ambient telemetry context. A single process-wide AsyncLocalStorage
5
5
  * holds the standard identifiers ({integrationId, integrationType, userId,
6
6
  * version, ...}) for the duration of a handler, set once at the handler seam via
7
7
  * `telemetry.withContext(...)`. Any emission during that async scope — including
@@ -1,6 +1,6 @@
1
1
  /**
2
- * TelemetryEventBus — the internal event stream telemetry flows onto
3
- * (ADR-011 Decision 6). Plugins/extensions and the built-in usage rollup
2
+ * TelemetryEventBus — the internal event stream telemetry flows onto.
3
+ * Plugins/extensions and the built-in usage rollup
4
4
  * subscribe here; it is deliberately independent of OTel export (Decision 7),
5
5
  * so usage counters persist even when the OTel exporter is a no-op.
6
6
  *
@@ -12,7 +12,7 @@ function isNoOpExporter(exporter) {
12
12
  }
13
13
 
14
14
  /**
15
- * Create the vendor-neutral telemetry service (ADR-011 Decision 1).
15
+ * Create the vendor-neutral telemetry service.
16
16
  *
17
17
  * Integration code uses the returned object (`this.telemetry`) and never imports
18
18
  * a backend SDK. When no exporter is configured the service is a pure no-op that
@@ -26,8 +26,8 @@ function isNoOpExporter(exporter) {
26
26
  * @param {object} [options.bus] Event bus to reuse (defaults to a fresh one).
27
27
  */
28
28
  function createTelemetry(options = {}) {
29
- // The internal event stream is always on and independent of OTel export
30
- // (ADR-011 Decision 7): the usage rollup + plugin taps must work even when
29
+ // The internal event stream is always on and independent of OTel export:
30
+ // the usage rollup + plugin taps must work even when
31
31
  // the OTel exporter is a no-op. The bus is pure JS, so this does not load
32
32
  // any OTel module on the no-op path.
33
33
  const bus = options.bus || createTelemetryEventBus();
@@ -2,7 +2,7 @@ const { createTelemetry } = require('./telemetry-service');
2
2
  const { createNoOpTelemetry } = require('./no-op-telemetry');
3
3
 
4
4
  /**
5
- * Process-wide telemetry singleton (ADR-011 P4). Created lazily on first use and
5
+ * Process-wide telemetry singleton. Created lazily on first use and
6
6
  * reused for the life of the Lambda container, so the OTel SDK initialises at
7
7
  * most once per cold start. Building it never throws — any failure (e.g. no app
8
8
  * definition on disk in a unit test) falls back to the no-op so a handler is
@@ -1,7 +1,7 @@
1
1
  const { createUsageRollupSubscriber } = require('./usage-rollup-subscriber');
2
2
 
3
3
  /**
4
- * Process-wide usage-rollup subscriber (ADR-011 P9). Built once per cold start,
4
+ * Process-wide usage-rollup subscriber. Built once per cold start,
5
5
  * subscribed to the telemetry singleton's bus, and reused across invocations.
6
6
  * Returns null when usage is disabled (no integration declares Definition.usage)
7
7
  * or when the app definition can't be loaded — the handler then skips the flush.
@@ -3,8 +3,8 @@ const { computeUsageWindows } = require('./usage-windows');
3
3
  const WEBHOOK_EVENT_NAMES = new Set(['ON_WEBHOOK']);
4
4
 
5
5
  /**
6
- * Framework auto-signal metric names → the canonical usage key they feed
7
- * (ADR-011 §3). Resolvers receive (attributes, context) and may return null to
6
+ * Framework auto-signal metric names → the canonical usage key they feed.
7
+ * Resolvers receive (attributes, context) and may return null to
8
8
  * decline. Handler invocations map by event: USER_ACTION → user_actions; the
9
9
  * DB-connected `ON_WEBHOOK` queue dispatch → webhooks.received (per-integration,
10
10
  * and where a durable write is actually possible — the HTTP receipt handler is
@@ -22,7 +22,7 @@ const METRIC_TO_CANONICAL = {
22
22
  };
23
23
 
24
24
  /**
25
- * The built-in usage-rollup subscriber (ADR-011 Decision 7). Subscribes to the
25
+ * The built-in usage-rollup subscriber. Subscribes to the
26
26
  * telemetry event bus and folds *declared* counters (canonical or custom) into
27
27
  * the durable usage store. It buffers within an invocation and writes on
28
28
  * `flush()` (no timers — Lambda-safe), or drops the buffer on `discard()` for an
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Compute the rollup window keys a usage event falls into (ADR-011 §4).
2
+ * Compute the rollup window keys a usage event falls into.
3
3
  * Windows are UTC and prefixed by their granularity so the store can filter a
4
4
  * series by bucket (`window startsWith 'day:'`).
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Port for the durable usage-counter store (ADR-011 Usage-Counter Contract §4).
2
+ * Port for the durable usage-counter store.
3
3
  *
4
4
  * The store is deliberately isolated (ADR-010 Decision 3): its fact rows carry
5
5
  * NO userId and NO foreign key to Integration, so a user-scoped query can never
@@ -2,7 +2,7 @@ const { prisma } = require('../../database/prisma');
2
2
  const { UsageRepositoryInterface } = require('./usage-repository-interface');
3
3
 
4
4
  /**
5
- * Prisma-backed usage store (ADR-011 §4). This is the canonical implementation;
5
+ * Prisma-backed usage store. This is the canonical implementation;
6
6
  * because Prisma abstracts the underlying database, the Mongo and DocumentDB
7
7
  * adapters extend this class unchanged (see their files). All queries touch only
8
8
  * the isolated `UsageCounter` model — never user/integration-scoped tables.
@@ -2,7 +2,7 @@ const { isCanonicalCounter } = require('../telemetry/canonical-counters');
2
2
 
3
3
  /**
4
4
  * Compute the set of usage-counter keys the rollup should persist, from each
5
- * integration's `Definition.usage` opt-in (ADR-011 Usage-Counter Contract §2).
5
+ * integration's `Definition.usage` opt-in.
6
6
  * Declaring a canonical key opts into cross-type comparison + the rollup; custom
7
7
  * keys are tracked per integration type. Unknown canonical keys are dropped with
8
8
  * a warning (lazy validation, matching how Definition is treated elsewhere).