@adonis-agora/flags 0.0.0-beta-20261112141227
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/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/dist/assets/spa/assets/index-DdmFo7xr.js +12 -0
- package/dist/assets/spa/assets/index-DdmFo7xr.js.map +1 -0
- package/dist/assets/spa/assets/index-DhkcP3Cw.css +2 -0
- package/dist/assets/spa/index.html +26 -0
- package/dist/commands/flags_list.d.ts +9 -0
- package/dist/commands/flags_list.d.ts.map +1 -0
- package/dist/commands/flags_list.js +51 -0
- package/dist/commands/flags_list.js.map +1 -0
- package/dist/commands/flags_ops.d.ts +60 -0
- package/dist/commands/flags_ops.d.ts.map +1 -0
- package/dist/commands/flags_ops.js +253 -0
- package/dist/commands/flags_ops.js.map +1 -0
- package/dist/commands/flags_refs.d.ts +15 -0
- package/dist/commands/flags_refs.d.ts.map +1 -0
- package/dist/commands/flags_refs.js +90 -0
- package/dist/commands/flags_refs.js.map +1 -0
- package/dist/commands/flags_set.d.ts +19 -0
- package/dist/commands/flags_set.d.ts.map +1 -0
- package/dist/commands/flags_set.js +97 -0
- package/dist/commands/flags_set.js.map +1 -0
- package/dist/commands/flags_types.d.ts +18 -0
- package/dist/commands/flags_types.d.ts.map +1 -0
- package/dist/commands/flags_types.js +94 -0
- package/dist/commands/flags_types.js.map +1 -0
- package/dist/commands/flags_work.d.ts +16 -0
- package/dist/commands/flags_work.d.ts.map +1 -0
- package/dist/commands/flags_work.js +71 -0
- package/dist/commands/flags_work.js.map +1 -0
- package/dist/commands/main.d.ts +15 -0
- package/dist/commands/main.d.ts.map +1 -0
- package/dist/commands/main.js +30 -0
- package/dist/commands/main.js.map +1 -0
- package/dist/commands/shared.d.ts +21 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +70 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/configure.d.ts +11 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +32 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/dashboard_provider.d.ts +65 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -0
- package/dist/providers/dashboard_provider.js +340 -0
- package/dist/providers/dashboard_provider.js.map +1 -0
- package/dist/providers/flags_provider.d.ts +30 -0
- package/dist/providers/flags_provider.d.ts.map +1 -0
- package/dist/providers/flags_provider.js +184 -0
- package/dist/providers/flags_provider.js.map +1 -0
- package/dist/services/main.d.ts +17 -0
- package/dist/services/main.d.ts.map +1 -0
- package/dist/services/main.js +20 -0
- package/dist/services/main.js.map +1 -0
- package/dist/src/admin.d.ts +189 -0
- package/dist/src/admin.d.ts.map +1 -0
- package/dist/src/admin.js +539 -0
- package/dist/src/admin.js.map +1 -0
- package/dist/src/analytics/backend.d.ts +18 -0
- package/dist/src/analytics/backend.d.ts.map +1 -0
- package/dist/src/analytics/backend.js +25 -0
- package/dist/src/analytics/backend.js.map +1 -0
- package/dist/src/analytics/clickhouse_backend.d.ts +16 -0
- package/dist/src/analytics/clickhouse_backend.d.ts.map +1 -0
- package/dist/src/analytics/clickhouse_backend.js +48 -0
- package/dist/src/analytics/clickhouse_backend.js.map +1 -0
- package/dist/src/analytics/duckdb.d.ts +39 -0
- package/dist/src/analytics/duckdb.d.ts.map +1 -0
- package/dist/src/analytics/duckdb.js +117 -0
- package/dist/src/analytics/duckdb.js.map +1 -0
- package/dist/src/analytics/lucid_backend.d.ts +16 -0
- package/dist/src/analytics/lucid_backend.d.ts.map +1 -0
- package/dist/src/analytics/lucid_backend.js +45 -0
- package/dist/src/analytics/lucid_backend.js.map +1 -0
- package/dist/src/analytics/metrics.d.ts +50 -0
- package/dist/src/analytics/metrics.d.ts.map +1 -0
- package/dist/src/analytics/metrics.js +42 -0
- package/dist/src/analytics/metrics.js.map +1 -0
- package/dist/src/analytics/results.d.ts +80 -0
- package/dist/src/analytics/results.d.ts.map +1 -0
- package/dist/src/analytics/results.js +143 -0
- package/dist/src/analytics/results.js.map +1 -0
- package/dist/src/dashboard/access_denied_page.d.ts +100 -0
- package/dist/src/dashboard/access_denied_page.d.ts.map +1 -0
- package/dist/src/dashboard/access_denied_page.js +262 -0
- package/dist/src/dashboard/access_denied_page.js.map +1 -0
- package/dist/src/dashboard/actor.d.ts +12 -0
- package/dist/src/dashboard/actor.d.ts.map +1 -0
- package/dist/src/dashboard/actor.js +33 -0
- package/dist/src/dashboard/actor.js.map +1 -0
- package/dist/src/dashboard/authorize_decision.d.ts +48 -0
- package/dist/src/dashboard/authorize_decision.d.ts.map +1 -0
- package/dist/src/dashboard/authorize_decision.js +44 -0
- package/dist/src/dashboard/authorize_decision.js.map +1 -0
- package/dist/src/dashboard/console_authorize.d.ts +77 -0
- package/dist/src/dashboard/console_authorize.d.ts.map +1 -0
- package/dist/src/dashboard/console_authorize.js +104 -0
- package/dist/src/dashboard/console_authorize.js.map +1 -0
- package/dist/src/dashboard/define_config.d.ts +71 -0
- package/dist/src/dashboard/define_config.d.ts.map +1 -0
- package/dist/src/dashboard/define_config.js +18 -0
- package/dist/src/dashboard/define_config.js.map +1 -0
- package/dist/src/dashboard/handlers.d.ts +172 -0
- package/dist/src/dashboard/handlers.d.ts.map +1 -0
- package/dist/src/dashboard/handlers.js +949 -0
- package/dist/src/dashboard/handlers.js.map +1 -0
- package/dist/src/dashboard/index.d.ts +15 -0
- package/dist/src/dashboard/index.d.ts.map +1 -0
- package/dist/src/dashboard/index.js +10 -0
- package/dist/src/dashboard/index.js.map +1 -0
- package/dist/src/dashboard/shape.d.ts +12 -0
- package/dist/src/dashboard/shape.d.ts.map +1 -0
- package/dist/src/dashboard/shape.js +232 -0
- package/dist/src/dashboard/shape.js.map +1 -0
- package/dist/src/dashboard/spa.d.ts +34 -0
- package/dist/src/dashboard/spa.d.ts.map +1 -0
- package/dist/src/dashboard/spa.js +50 -0
- package/dist/src/dashboard/spa.js.map +1 -0
- package/dist/src/declare.d.ts +85 -0
- package/dist/src/declare.d.ts.map +1 -0
- package/dist/src/declare.js +62 -0
- package/dist/src/declare.js.map +1 -0
- package/dist/src/define_config.d.ts +256 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +90 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/durable.d.ts +29 -0
- package/dist/src/durable.d.ts.map +1 -0
- package/dist/src/durable.js +55 -0
- package/dist/src/durable.js.map +1 -0
- package/dist/src/enrichers.d.ts +51 -0
- package/dist/src/enrichers.d.ts.map +1 -0
- package/dist/src/enrichers.js +105 -0
- package/dist/src/enrichers.js.map +1 -0
- package/dist/src/events/buffer.d.ts +38 -0
- package/dist/src/events/buffer.d.ts.map +1 -0
- package/dist/src/events/buffer.js +86 -0
- package/dist/src/events/buffer.js.map +1 -0
- package/dist/src/events/event.d.ts +42 -0
- package/dist/src/events/event.d.ts.map +1 -0
- package/dist/src/events/event.js +82 -0
- package/dist/src/events/event.js.map +1 -0
- package/dist/src/http/browser.d.ts +33 -0
- package/dist/src/http/browser.d.ts.map +1 -0
- package/dist/src/http/browser.js +81 -0
- package/dist/src/http/browser.js.map +1 -0
- package/dist/src/http/browser_api.d.ts +48 -0
- package/dist/src/http/browser_api.d.ts.map +1 -0
- package/dist/src/http/browser_api.js +273 -0
- package/dist/src/http/browser_api.js.map +1 -0
- package/dist/src/http/browser_tokens.d.ts +27 -0
- package/dist/src/http/browser_tokens.d.ts.map +1 -0
- package/dist/src/http/browser_tokens.js +48 -0
- package/dist/src/http/browser_tokens.js.map +1 -0
- package/dist/src/http/control_plane.d.ts +58 -0
- package/dist/src/http/control_plane.d.ts.map +1 -0
- package/dist/src/http/control_plane.js +318 -0
- package/dist/src/http/control_plane.js.map +1 -0
- package/dist/src/http/csrf.d.ts +22 -0
- package/dist/src/http/csrf.d.ts.map +1 -0
- package/dist/src/http/csrf.js +24 -0
- package/dist/src/http/csrf.js.map +1 -0
- package/dist/src/http/edge_tag.d.ts +55 -0
- package/dist/src/http/edge_tag.d.ts.map +1 -0
- package/dist/src/http/edge_tag.js +45 -0
- package/dist/src/http/edge_tag.js.map +1 -0
- package/dist/src/http/flag_middleware.d.ts +27 -0
- package/dist/src/http/flag_middleware.d.ts.map +1 -0
- package/dist/src/http/flag_middleware.js +30 -0
- package/dist/src/http/flag_middleware.js.map +1 -0
- package/dist/src/http/flags_middleware.d.ts +20 -0
- package/dist/src/http/flags_middleware.d.ts.map +1 -0
- package/dist/src/http/flags_middleware.js +20 -0
- package/dist/src/http/flags_middleware.js.map +1 -0
- package/dist/src/http/subject_resolver.d.ts +45 -0
- package/dist/src/http/subject_resolver.d.ts.map +1 -0
- package/dist/src/http/subject_resolver.js +93 -0
- package/dist/src/http/subject_resolver.js.map +1 -0
- package/dist/src/identity.d.ts +82 -0
- package/dist/src/identity.d.ts.map +1 -0
- package/dist/src/identity.js +100 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/index.d.ts +41 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +34 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/manager.d.ts +154 -0
- package/dist/src/manager.d.ts.map +1 -0
- package/dist/src/manager.js +333 -0
- package/dist/src/manager.js.map +1 -0
- package/dist/src/openfeature/provider.d.ts +36 -0
- package/dist/src/openfeature/provider.d.ts.map +1 -0
- package/dist/src/openfeature/provider.js +82 -0
- package/dist/src/openfeature/provider.js.map +1 -0
- package/dist/src/relay/relay.d.ts +36 -0
- package/dist/src/relay/relay.d.ts.map +1 -0
- package/dist/src/relay/relay.js +73 -0
- package/dist/src/relay/relay.js.map +1 -0
- package/dist/src/relay/results_cache.d.ts +20 -0
- package/dist/src/relay/results_cache.d.ts.map +1 -0
- package/dist/src/relay/results_cache.js +31 -0
- package/dist/src/relay/results_cache.js.map +1 -0
- package/dist/src/relay/worker.d.ts +66 -0
- package/dist/src/relay/worker.d.ts.map +1 -0
- package/dist/src/relay/worker.js +177 -0
- package/dist/src/relay/worker.js.map +1 -0
- package/dist/src/ruleset_source.d.ts +73 -0
- package/dist/src/ruleset_source.d.ts.map +1 -0
- package/dist/src/ruleset_source.js +128 -0
- package/dist/src/ruleset_source.js.map +1 -0
- package/dist/src/runtime.d.ts +70 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +301 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/schema.d.ts +39 -0
- package/dist/src/schema.d.ts.map +1 -0
- package/dist/src/schema.js +311 -0
- package/dist/src/schema.js.map +1 -0
- package/dist/src/services/accessor.d.ts +5 -0
- package/dist/src/services/accessor.d.ts.map +1 -0
- package/dist/src/services/accessor.js +20 -0
- package/dist/src/services/accessor.js.map +1 -0
- package/dist/src/sinks/clickhouse.d.ts +41 -0
- package/dist/src/sinks/clickhouse.d.ts.map +1 -0
- package/dist/src/sinks/clickhouse.js +117 -0
- package/dist/src/sinks/clickhouse.js.map +1 -0
- package/dist/src/sinks/lucid_sink.d.ts +25 -0
- package/dist/src/sinks/lucid_sink.d.ts.map +1 -0
- package/dist/src/sinks/lucid_sink.js +87 -0
- package/dist/src/sinks/lucid_sink.js.map +1 -0
- package/dist/src/sinks/parquet_sink.d.ts +41 -0
- package/dist/src/sinks/parquet_sink.d.ts.map +1 -0
- package/dist/src/sinks/parquet_sink.js +140 -0
- package/dist/src/sinks/parquet_sink.js.map +1 -0
- package/dist/src/sinks/posthog_sink.d.ts +29 -0
- package/dist/src/sinks/posthog_sink.d.ts.map +1 -0
- package/dist/src/sinks/posthog_sink.js +65 -0
- package/dist/src/sinks/posthog_sink.js.map +1 -0
- package/dist/src/sinks/sink.d.ts +36 -0
- package/dist/src/sinks/sink.d.ts.map +1 -0
- package/dist/src/sinks/sink.js +36 -0
- package/dist/src/sinks/sink.js.map +1 -0
- package/dist/src/sql.d.ts +33 -0
- package/dist/src/sql.d.ts.map +1 -0
- package/dist/src/sql.js +66 -0
- package/dist/src/sql.js.map +1 -0
- package/dist/src/stores/lucid_store.d.ts +55 -0
- package/dist/src/stores/lucid_store.d.ts.map +1 -0
- package/dist/src/stores/lucid_store.js +412 -0
- package/dist/src/stores/lucid_store.js.map +1 -0
- package/dist/src/stores/memory_store.d.ts +38 -0
- package/dist/src/stores/memory_store.d.ts.map +1 -0
- package/dist/src/stores/memory_store.js +166 -0
- package/dist/src/stores/memory_store.js.map +1 -0
- package/dist/src/stores/store.d.ts +166 -0
- package/dist/src/stores/store.d.ts.map +1 -0
- package/dist/src/stores/store.js +67 -0
- package/dist/src/stores/store.js.map +1 -0
- package/dist/src/subject.d.ts +25 -0
- package/dist/src/subject.d.ts.map +1 -0
- package/dist/src/subject.js +30 -0
- package/dist/src/subject.js.map +1 -0
- package/dist/src/testing/index.d.ts +31 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +60 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/topology/browser_token.d.ts +48 -0
- package/dist/src/topology/browser_token.d.ts.map +1 -0
- package/dist/src/topology/browser_token.js +128 -0
- package/dist/src/topology/browser_token.js.map +1 -0
- package/dist/src/topology/remote_source.d.ts +39 -0
- package/dist/src/topology/remote_source.d.ts.map +1 -0
- package/dist/src/topology/remote_source.js +184 -0
- package/dist/src/topology/remote_source.js.map +1 -0
- package/dist/src/topology/token.d.ts +36 -0
- package/dist/src/topology/token.d.ts.map +1 -0
- package/dist/src/topology/token.js +68 -0
- package/dist/src/topology/token.js.map +1 -0
- package/dist/src/topology/verify.d.ts +88 -0
- package/dist/src/topology/verify.d.ts.map +1 -0
- package/dist/src/topology/verify.js +128 -0
- package/dist/src/topology/verify.js.map +1 -0
- package/dist/src/transports/db_transport.d.ts +55 -0
- package/dist/src/transports/db_transport.d.ts.map +1 -0
- package/dist/src/transports/db_transport.js +202 -0
- package/dist/src/transports/db_transport.js.map +1 -0
- package/dist/src/transports/http_transport.d.ts +30 -0
- package/dist/src/transports/http_transport.d.ts.map +1 -0
- package/dist/src/transports/http_transport.js +51 -0
- package/dist/src/transports/http_transport.js.map +1 -0
- package/dist/src/transports/memory_transport.d.ts +29 -0
- package/dist/src/transports/memory_transport.d.ts.map +1 -0
- package/dist/src/transports/memory_transport.js +91 -0
- package/dist/src/transports/memory_transport.js.map +1 -0
- package/dist/src/transports/redis_transport.d.ts +50 -0
- package/dist/src/transports/redis_transport.d.ts.map +1 -0
- package/dist/src/transports/redis_transport.js +107 -0
- package/dist/src/transports/redis_transport.js.map +1 -0
- package/dist/src/transports/transport.d.ts +62 -0
- package/dist/src/transports/transport.d.ts.map +1 -0
- package/dist/src/transports/transport.js +2 -0
- package/dist/src/transports/transport.js.map +1 -0
- package/dist/src/types.d.ts +30 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/usage.d.ts +18 -0
- package/dist/src/usage.d.ts.map +1 -0
- package/dist/src/usage.js +52 -0
- package/dist/src/usage.js.map +1 -0
- package/dist/stubs/config/flags.stub +50 -0
- package/dist/stubs/config/flags_dashboard.stub +35 -0
- package/dist/stubs/database/migrations/create_flags_tables.stub +27 -0
- package/dist/stubs/main.d.ts +3 -0
- package/dist/stubs/main.d.ts.map +1 -0
- package/dist/stubs/main.js +9 -0
- package/dist/stubs/main.js.map +1 -0
- package/package.json +181 -0
- package/skills/flags-basics/SKILL.md +142 -0
- package/skills/flags-deployment/SKILL.md +125 -0
- package/skills/flags-experiments/SKILL.md +99 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsonValue, parseJson, query } from '../sql.js';
|
|
2
|
+
export class MemoryResultsCache {
|
|
3
|
+
#map = new Map();
|
|
4
|
+
async get(environment, experiment) {
|
|
5
|
+
return this.#map.get(`${environment}\u0000${experiment}`) ?? null;
|
|
6
|
+
}
|
|
7
|
+
async set(environment, experiment, results) {
|
|
8
|
+
this.#map.set(`${environment}\u0000${experiment}`, results);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** `flags_results`, shared by every replica. */
|
|
12
|
+
export class LucidResultsCache {
|
|
13
|
+
db;
|
|
14
|
+
constructor(db) {
|
|
15
|
+
this.db = db;
|
|
16
|
+
}
|
|
17
|
+
async get(environment, experiment) {
|
|
18
|
+
const rows = await query(this.db, 'SELECT payload FROM flags_results WHERE environment = ? AND experiment = ?', [environment, experiment]);
|
|
19
|
+
return rows[0] ? parseJson(rows[0].payload) : null;
|
|
20
|
+
}
|
|
21
|
+
async set(environment, experiment, results) {
|
|
22
|
+
await this.db.transaction(async (trx) => {
|
|
23
|
+
await trx.rawQuery('DELETE FROM flags_results WHERE environment = ? AND experiment = ?', [
|
|
24
|
+
environment,
|
|
25
|
+
experiment,
|
|
26
|
+
]);
|
|
27
|
+
await trx.rawQuery('INSERT INTO flags_results (environment, experiment, payload, computed_at) VALUES (?, ?, ?, ?)', [environment, experiment, jsonValue(results), Date.now()]);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=results_cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"results_cache.js","sourceRoot":"","sources":["../../../src/relay/results_cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAoB,MAAM,WAAW,CAAC;AAQ1E,MAAM,OAAO,kBAAkB;IAC7B,IAAI,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC5C,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,UAAkB;QAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,SAAS,UAAU,EAAE,CAAC,IAAI,IAAI,CAAC;IACpE,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,UAAkB,EAAE,OAA0B;QAC3E,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,SAAS,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;CACF;AAED,gDAAgD;AAChD,MAAM,OAAO,iBAAiB;IACC,EAAE;IAA/B,YAA6B,EAAe;kBAAf,EAAE;IAAgB,CAAC;IAEhD,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,UAAkB;QAC/C,MAAM,IAAI,GAAG,MAAM,KAAK,CACtB,IAAI,CAAC,EAAE,EACP,4EAA4E,EAC5E,CAAC,WAAW,EAAE,UAAU,CAAC,CAC1B,CAAC;QACF,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAoB,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,WAAmB,EAAE,UAAkB,EAAE,OAA0B;QAC3E,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACtC,MAAM,GAAG,CAAC,QAAQ,CAAC,oEAAoE,EAAE;gBACvF,WAAW;gBACX,UAAU;aACX,CAAC,CAAC;YACH,MAAM,GAAG,CAAC,QAAQ,CAChB,+FAA+F,EAC/F,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAC1D,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { FlagsAdmin } from '../admin.js';
|
|
2
|
+
import type { AnalyticsBackend } from '../analytics/backend.js';
|
|
3
|
+
import type { MetricDefinition } from '../analytics/metrics.js';
|
|
4
|
+
import { type ExperimentResults } from '../analytics/results.js';
|
|
5
|
+
import type { ExperimentConfig } from '../define_config.js';
|
|
6
|
+
import type { RulesetSource } from '../ruleset_source.js';
|
|
7
|
+
import type { SqlClient } from '../sql.js';
|
|
8
|
+
import type { Transport } from '../transports/transport.js';
|
|
9
|
+
import type { Relay } from './relay.js';
|
|
10
|
+
import type { ResultsCache } from './results_cache.js';
|
|
11
|
+
export interface WorkerOptions {
|
|
12
|
+
relay?: Relay;
|
|
13
|
+
/** Default drain interval per sink (ms). */
|
|
14
|
+
relayIntervalMs?: number;
|
|
15
|
+
admin?: FlagsAdmin;
|
|
16
|
+
source: RulesetSource;
|
|
17
|
+
/** The environment this process reads (results default to it). */
|
|
18
|
+
environment?: string;
|
|
19
|
+
/** Environments whose experiment results the worker recomputes. Default: `[environment]`. */
|
|
20
|
+
resultsEnvironments?: string[];
|
|
21
|
+
analytics?: AnalyticsBackend;
|
|
22
|
+
resultsCache?: ResultsCache;
|
|
23
|
+
metrics?: Record<string, MetricDefinition>;
|
|
24
|
+
experiments?: Record<string, ExperimentConfig>;
|
|
25
|
+
resultsIntervalMs?: number;
|
|
26
|
+
transport?: Transport;
|
|
27
|
+
/** The db transport's client, for partition maintenance and pruning. */
|
|
28
|
+
eventsDb?: SqlClient;
|
|
29
|
+
retentionDays?: number;
|
|
30
|
+
logger?: {
|
|
31
|
+
info?(message: string): void;
|
|
32
|
+
warn(message: string): void;
|
|
33
|
+
error(message: string): void;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export type TaskName = 'relay' | 'schedules' | 'results' | 'maintenance';
|
|
37
|
+
/**
|
|
38
|
+
* The background work of a flags deployment: relaying events to sinks, executing scheduled changes,
|
|
39
|
+
* recomputing experiment results, and maintaining the event log. Every task is safe to run on many
|
|
40
|
+
* replicas at once (leases, schedule claims, idempotent writes), so where it runs is a deployment
|
|
41
|
+
* choice (`role` / `dispatcher`), not a correctness one.
|
|
42
|
+
*/
|
|
43
|
+
export declare class FlagsWorker {
|
|
44
|
+
#private;
|
|
45
|
+
readonly options: WorkerOptions;
|
|
46
|
+
constructor(options: WorkerOptions);
|
|
47
|
+
/** Runs whatever is due. In-process mode calls this every second. */
|
|
48
|
+
tick(now?: number): Promise<void>;
|
|
49
|
+
/** Runs every task once, regardless of schedule (`flags:work --once`). */
|
|
50
|
+
runAll(): Promise<void>;
|
|
51
|
+
relaySink(name: string): Promise<import("./relay.js").DrainResult | undefined>;
|
|
52
|
+
runSchedules(): Promise<{
|
|
53
|
+
id: string;
|
|
54
|
+
ok: boolean;
|
|
55
|
+
error?: string;
|
|
56
|
+
}[]>;
|
|
57
|
+
/** Recomputes and caches results for every configured experiment. */
|
|
58
|
+
computeAllResults(): Promise<ExperimentResults[]>;
|
|
59
|
+
/** Computes and caches one experiment's results for an environment (default: this process's). */
|
|
60
|
+
computeResults(key: string, environment?: string): Promise<ExperimentResults | null>;
|
|
61
|
+
maintenance(): Promise<void>;
|
|
62
|
+
/** In-process scheduling: a 1s timer that runs what is due. */
|
|
63
|
+
start(): void;
|
|
64
|
+
stop(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/relay/worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzE;;;;;GAKG;AACH,qBAAa,WAAW;;IAKV,QAAQ,CAAC,OAAO,EAAE,aAAa;IAA3C,YAAqB,OAAO,EAAE,aAAa,EAAI;IAU/C,qEAAqE;IAC/D,IAAI,CAAC,GAAG,SAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB1C;IAED,0EAA0E;IACpE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAK5B;IAEK,SAAS,CAAC,IAAI,EAAE,MAAM,yDAS3B;IAEK,YAAY;;;;SAYjB;IAED,qEAAqE;IAC/D,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAkBtD;IAMD,iGAAiG;IAC3F,cAAc,CAClB,GAAG,EAAE,MAAM,EACX,WAAW,SAAoB,GAC9B,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA2CnC;IAEK,WAAW,kBAYhB;IAED,+DAA+D;IAC/D,KAAK,SAGJ;IAEK,IAAI,kBAKT;CACF"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { computeResults } from '../analytics/results.js';
|
|
2
|
+
import { ensureEventPartitions, pruneEvents } from '../schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* The background work of a flags deployment: relaying events to sinks, executing scheduled changes,
|
|
5
|
+
* recomputing experiment results, and maintaining the event log. Every task is safe to run on many
|
|
6
|
+
* replicas at once (leases, schedule claims, idempotent writes), so where it runs is a deployment
|
|
7
|
+
* choice (`role` / `dispatcher`), not a correctness one.
|
|
8
|
+
*/
|
|
9
|
+
export class FlagsWorker {
|
|
10
|
+
options;
|
|
11
|
+
#timer;
|
|
12
|
+
#nextRun = new Map();
|
|
13
|
+
#running = false;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
}
|
|
17
|
+
/** Due-ness check for in-process scheduling. */
|
|
18
|
+
#due(key, intervalMs, now) {
|
|
19
|
+
const next = this.#nextRun.get(key) ?? 0;
|
|
20
|
+
if (now < next)
|
|
21
|
+
return false;
|
|
22
|
+
this.#nextRun.set(key, now + intervalMs);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
/** Runs whatever is due. In-process mode calls this every second. */
|
|
26
|
+
async tick(now = Date.now()) {
|
|
27
|
+
if (this.#running)
|
|
28
|
+
return;
|
|
29
|
+
this.#running = true;
|
|
30
|
+
try {
|
|
31
|
+
const relay = this.options.relay;
|
|
32
|
+
if (relay) {
|
|
33
|
+
for (const name of relay.sinkNames) {
|
|
34
|
+
const interval = relay.sink(name)?.intervalMs ?? this.options.relayIntervalMs ?? 5000;
|
|
35
|
+
if (this.#due(`relay:${name}`, interval, now))
|
|
36
|
+
await this.relaySink(name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (this.options.admin && this.#due('schedules', 15_000, now))
|
|
40
|
+
await this.runSchedules();
|
|
41
|
+
if (this.#due('results', this.options.resultsIntervalMs ?? 600_000, now))
|
|
42
|
+
await this.computeAllResults();
|
|
43
|
+
if (this.#due('maintenance', 3_600_000, now))
|
|
44
|
+
await this.maintenance();
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
this.#running = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Runs every task once, regardless of schedule (`flags:work --once`). */
|
|
51
|
+
async runAll() {
|
|
52
|
+
for (const name of this.options.relay?.sinkNames ?? [])
|
|
53
|
+
await this.relaySink(name);
|
|
54
|
+
await this.runSchedules();
|
|
55
|
+
await this.computeAllResults();
|
|
56
|
+
await this.maintenance();
|
|
57
|
+
}
|
|
58
|
+
async relaySink(name) {
|
|
59
|
+
try {
|
|
60
|
+
const result = await this.options.relay.drain(name);
|
|
61
|
+
if (result.error)
|
|
62
|
+
this.options.logger?.warn(`[flags] sink "${name}" failed: ${result.error}`);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
this.options.logger?.error(`[flags] relay to "${name}" crashed: ${error.message}`);
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async runSchedules() {
|
|
71
|
+
if (!this.options.admin)
|
|
72
|
+
return [];
|
|
73
|
+
try {
|
|
74
|
+
const results = await this.options.admin.runDueSchedules();
|
|
75
|
+
for (const r of results) {
|
|
76
|
+
if (!r.ok)
|
|
77
|
+
this.options.logger?.warn(`[flags] scheduled change ${r.id} failed: ${r.error}`);
|
|
78
|
+
}
|
|
79
|
+
return results;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
this.options.logger?.error(`[flags] schedules crashed: ${error.message}`);
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Recomputes and caches results for every configured experiment. */
|
|
87
|
+
async computeAllResults() {
|
|
88
|
+
const { analytics, resultsCache, experiments } = this.options;
|
|
89
|
+
if (!analytics || !resultsCache || !experiments)
|
|
90
|
+
return [];
|
|
91
|
+
const out = [];
|
|
92
|
+
const environments = this.options.resultsEnvironments ?? [this.#environment];
|
|
93
|
+
for (const environment of environments) {
|
|
94
|
+
for (const key of Object.keys(experiments)) {
|
|
95
|
+
try {
|
|
96
|
+
const result = await this.computeResults(key, environment);
|
|
97
|
+
if (result)
|
|
98
|
+
out.push(result);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.options.logger?.error(`[flags] results for "${key}" (${environment}) failed: ${error.message}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}
|
|
107
|
+
get #environment() {
|
|
108
|
+
return this.options.environment ?? 'production';
|
|
109
|
+
}
|
|
110
|
+
/** Computes and caches one experiment's results for an environment (default: this process's). */
|
|
111
|
+
async computeResults(key, environment = this.#environment) {
|
|
112
|
+
const { analytics, resultsCache, experiments, metrics = {} } = this.options;
|
|
113
|
+
const experiment = experiments?.[key];
|
|
114
|
+
if (!analytics || !resultsCache || !experiment)
|
|
115
|
+
return null;
|
|
116
|
+
const flagKey = experiment.flag ?? key;
|
|
117
|
+
const ruleset = environment === this.#environment || !this.options.admin
|
|
118
|
+
? this.options.source.current()
|
|
119
|
+
: await this.options.admin.store.readRuleset(environment);
|
|
120
|
+
const definitions = {};
|
|
121
|
+
for (const name of new Set([...experiment.metrics, ...(experiment.guardrails ?? [])])) {
|
|
122
|
+
const definition = metrics[name];
|
|
123
|
+
if (!definition)
|
|
124
|
+
throw new Error(`experiment "${key}" uses unknown metric "${name}"`);
|
|
125
|
+
definitions[name] = definition;
|
|
126
|
+
}
|
|
127
|
+
const previous = (await resultsCache.get(environment, key)) ?? undefined;
|
|
128
|
+
const result = await computeResults(analytics, {
|
|
129
|
+
key,
|
|
130
|
+
flag: flagKey,
|
|
131
|
+
environment,
|
|
132
|
+
metrics: definitions,
|
|
133
|
+
...(experiment.guardrails ? { guardrails: experiment.guardrails } : {}),
|
|
134
|
+
...(experiment.control ? { control: experiment.control } : {}),
|
|
135
|
+
...(experiment.confidence ? { confidence: experiment.confidence } : {}),
|
|
136
|
+
}, ruleset.flags[flagKey], previous);
|
|
137
|
+
await resultsCache.set(environment, key, result);
|
|
138
|
+
for (const metric of result.metrics) {
|
|
139
|
+
if (metric.alert)
|
|
140
|
+
this.options.logger?.warn(`[flags] guardrail "${metric.name}" regressed in experiment "${key}"`);
|
|
141
|
+
}
|
|
142
|
+
if (result.srm?.mismatch) {
|
|
143
|
+
this.options.logger?.warn(`[flags] experiment "${key}" has a sample ratio mismatch (p=${result.srm.pValue.toExponential(2)})`);
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
async maintenance() {
|
|
148
|
+
const db = this.options.eventsDb;
|
|
149
|
+
if (!db)
|
|
150
|
+
return;
|
|
151
|
+
try {
|
|
152
|
+
await ensureEventPartitions(db, Date.now());
|
|
153
|
+
const sinks = this.options.relay?.sinkNames ?? [];
|
|
154
|
+
const safeId = (await this.options.transport?.safePruneId?.(sinks)) ?? 0;
|
|
155
|
+
const before = Date.now() - (this.options.retentionDays ?? 30) * 86_400_000;
|
|
156
|
+
if (safeId > 0)
|
|
157
|
+
await pruneEvents(db, before, safeId);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
this.options.logger?.error(`[flags] maintenance failed: ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** In-process scheduling: a 1s timer that runs what is due. */
|
|
164
|
+
start() {
|
|
165
|
+
this.#timer ??= setInterval(() => void this.tick(), 1000);
|
|
166
|
+
this.#timer.unref();
|
|
167
|
+
}
|
|
168
|
+
async stop() {
|
|
169
|
+
if (this.#timer)
|
|
170
|
+
clearInterval(this.#timer);
|
|
171
|
+
this.#timer = undefined;
|
|
172
|
+
// Let a tick in progress finish.
|
|
173
|
+
while (this.#running)
|
|
174
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/relay/worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type Ruleset } from '@adonis-agora/flags-core';
|
|
2
|
+
import type { FlagsStore } from './stores/store.js';
|
|
3
|
+
export interface SourceStatus {
|
|
4
|
+
version: string;
|
|
5
|
+
loadedAt: Date | null;
|
|
6
|
+
lastError: string | null;
|
|
7
|
+
/** Serving a ruleset loaded before the latest failure (last known good). */
|
|
8
|
+
stale: boolean;
|
|
9
|
+
/** How the source learns about changes right now. */
|
|
10
|
+
mode: 'notify' | 'poll' | 'stream';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Where a process gets its ruleset. Every implementation keeps the last ruleset it loaded and serves
|
|
14
|
+
* it when the backing store or the control-plane is unreachable — evaluation never waits on I/O.
|
|
15
|
+
*/
|
|
16
|
+
export interface RulesetSource {
|
|
17
|
+
start(): Promise<void>;
|
|
18
|
+
current(): Ruleset;
|
|
19
|
+
/** Reloads if the version moved. Resolves `true` when a new ruleset was loaded. */
|
|
20
|
+
refresh(): Promise<boolean>;
|
|
21
|
+
onChange(listener: (ruleset: Ruleset) => void): () => void;
|
|
22
|
+
status(): SourceStatus;
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
declare abstract class BaseSource implements RulesetSource {
|
|
26
|
+
#private;
|
|
27
|
+
protected ruleset: Ruleset;
|
|
28
|
+
protected loadedAt: Date | null;
|
|
29
|
+
protected lastError: string | null;
|
|
30
|
+
abstract start(): Promise<void>;
|
|
31
|
+
abstract refresh(): Promise<boolean>;
|
|
32
|
+
abstract stop(): Promise<void>;
|
|
33
|
+
abstract status(): SourceStatus;
|
|
34
|
+
current(): Ruleset;
|
|
35
|
+
onChange(listener: (ruleset: Ruleset) => void): () => void;
|
|
36
|
+
protected set(ruleset: Ruleset): void;
|
|
37
|
+
}
|
|
38
|
+
/** A ruleset the app sets by hand (tests, `flags.fake()`, static configs). */
|
|
39
|
+
export declare class StaticSource extends BaseSource {
|
|
40
|
+
constructor(ruleset?: Ruleset);
|
|
41
|
+
start(): Promise<void>;
|
|
42
|
+
refresh(): Promise<boolean>;
|
|
43
|
+
stop(): Promise<void>;
|
|
44
|
+
replace(ruleset: Ruleset): void;
|
|
45
|
+
status(): SourceStatus;
|
|
46
|
+
}
|
|
47
|
+
export interface StoreSourceOptions {
|
|
48
|
+
environment: string;
|
|
49
|
+
/** Version poll interval (ms). Default 5000; the fallback when notifications are unavailable. */
|
|
50
|
+
intervalMs?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Subscribe to change notifications (Postgres `LISTEN`) for near-instant propagation. Holds one
|
|
53
|
+
* pool connection per process. Default `true` when the store supports it.
|
|
54
|
+
*/
|
|
55
|
+
notify?: boolean;
|
|
56
|
+
onError?: (error: unknown) => void;
|
|
57
|
+
}
|
|
58
|
+
/** Store-backed source for `standalone` and `control-plane` processes. */
|
|
59
|
+
export declare class StoreSource extends BaseSource {
|
|
60
|
+
#private;
|
|
61
|
+
private readonly store;
|
|
62
|
+
private readonly options;
|
|
63
|
+
constructor(store: FlagsStore & {
|
|
64
|
+
listen?(onMessage: (payload: string) => void): Promise<() => Promise<void>>;
|
|
65
|
+
canListen?: boolean;
|
|
66
|
+
}, options: StoreSourceOptions);
|
|
67
|
+
start(): Promise<void>;
|
|
68
|
+
refresh(): Promise<boolean>;
|
|
69
|
+
status(): SourceStatus;
|
|
70
|
+
stop(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=ruleset_source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleset_source.d.ts","sourceRoot":"","sources":["../../src/ruleset_source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,4EAA4E;IAC5E,KAAK,EAAE,OAAO,CAAC;IACf,qDAAqD;IACrD,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,IAAI,OAAO,CAAC;IACnB,mFAAmF;IACnF,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC3D,MAAM,IAAI,YAAY,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,uBAAe,UAAW,YAAW,aAAa;;IAChD,SAAS,CAAC,OAAO,EAAE,OAAO,CAAqB;IAC/C,SAAS,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAQ;IACvC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG1C,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,CAAC,MAAM,IAAI,YAAY,CAAC;IAEhC,OAAO,IAAI,OAAO,CAEjB;IAED,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAGzD;IAED,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,QAW7B;CACF;AAED,8EAA8E;AAC9E,qBAAa,YAAa,SAAQ,UAAU;IAC1C,YAAY,OAAO,GAAE,OAA2B,EAI/C;IAEK,KAAK,kBAAK;IACV,OAAO,qBAEZ;IACK,IAAI,kBAAK;IACf,OAAO,CAAC,OAAO,EAAE,OAAO,QAEvB;IACD,MAAM,IAAI,YAAY,CAQrB;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,0EAA0E;AAC1E,qBAAa,WAAY,SAAQ,UAAU;;IAMvC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAItB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,YACmB,KAAK,EAAE,UAAU,GAAG;QACnC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5E,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,EACgB,OAAO,EAAE,kBAAkB,EAG7C;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAiB3B;IAED,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAK1B;IAsBD,MAAM,IAAI,YAAY,CAQrB;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAK1B;CACF"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { emptyRuleset } from '@adonis-agora/flags-core';
|
|
2
|
+
class BaseSource {
|
|
3
|
+
ruleset = emptyRuleset('0');
|
|
4
|
+
loadedAt = null;
|
|
5
|
+
lastError = null;
|
|
6
|
+
#listeners = new Set();
|
|
7
|
+
current() {
|
|
8
|
+
return this.ruleset;
|
|
9
|
+
}
|
|
10
|
+
onChange(listener) {
|
|
11
|
+
this.#listeners.add(listener);
|
|
12
|
+
return () => this.#listeners.delete(listener);
|
|
13
|
+
}
|
|
14
|
+
set(ruleset) {
|
|
15
|
+
this.ruleset = ruleset;
|
|
16
|
+
this.loadedAt = new Date();
|
|
17
|
+
this.lastError = null;
|
|
18
|
+
for (const listener of this.#listeners) {
|
|
19
|
+
try {
|
|
20
|
+
listener(ruleset);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// A listener must never break reloading.
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** A ruleset the app sets by hand (tests, `flags.fake()`, static configs). */
|
|
29
|
+
export class StaticSource extends BaseSource {
|
|
30
|
+
constructor(ruleset = emptyRuleset('0')) {
|
|
31
|
+
super();
|
|
32
|
+
this.ruleset = ruleset;
|
|
33
|
+
this.loadedAt = new Date();
|
|
34
|
+
}
|
|
35
|
+
async start() { }
|
|
36
|
+
async refresh() {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
async stop() { }
|
|
40
|
+
replace(ruleset) {
|
|
41
|
+
this.set(ruleset);
|
|
42
|
+
}
|
|
43
|
+
status() {
|
|
44
|
+
return {
|
|
45
|
+
version: this.ruleset.version,
|
|
46
|
+
loadedAt: this.loadedAt,
|
|
47
|
+
lastError: null,
|
|
48
|
+
stale: false,
|
|
49
|
+
mode: 'poll',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Store-backed source for `standalone` and `control-plane` processes. */
|
|
54
|
+
export class StoreSource extends BaseSource {
|
|
55
|
+
store;
|
|
56
|
+
options;
|
|
57
|
+
#timer;
|
|
58
|
+
#unlisten;
|
|
59
|
+
#refreshing;
|
|
60
|
+
constructor(store, options) {
|
|
61
|
+
super();
|
|
62
|
+
this.store = store;
|
|
63
|
+
this.options = options;
|
|
64
|
+
}
|
|
65
|
+
async start() {
|
|
66
|
+
try {
|
|
67
|
+
this.set(await this.store.readRuleset(this.options.environment));
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
this.#fail(error);
|
|
71
|
+
}
|
|
72
|
+
if (this.options.notify !== false && this.store.listen && this.store.canListen !== false) {
|
|
73
|
+
try {
|
|
74
|
+
this.#unlisten = await this.store.listen((payload) => {
|
|
75
|
+
if (payload.startsWith(`${this.options.environment}:`))
|
|
76
|
+
void this.refresh();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.#fail(error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this.#timer = setInterval(() => void this.refresh(), this.options.intervalMs ?? 5000);
|
|
84
|
+
this.#timer.unref();
|
|
85
|
+
}
|
|
86
|
+
refresh() {
|
|
87
|
+
this.#refreshing ??= this.#refresh().finally(() => {
|
|
88
|
+
this.#refreshing = undefined;
|
|
89
|
+
});
|
|
90
|
+
return this.#refreshing;
|
|
91
|
+
}
|
|
92
|
+
async #refresh() {
|
|
93
|
+
try {
|
|
94
|
+
const version = await this.store.version(this.options.environment);
|
|
95
|
+
if (version === this.ruleset.version && this.loadedAt) {
|
|
96
|
+
this.lastError = null;
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
this.set(await this.store.readRuleset(this.options.environment));
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
this.#fail(error);
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
#fail(error) {
|
|
108
|
+
this.lastError = error instanceof Error ? error.message : String(error);
|
|
109
|
+
this.options.onError?.(error);
|
|
110
|
+
}
|
|
111
|
+
status() {
|
|
112
|
+
return {
|
|
113
|
+
version: this.ruleset.version,
|
|
114
|
+
loadedAt: this.loadedAt,
|
|
115
|
+
lastError: this.lastError,
|
|
116
|
+
stale: this.lastError !== null && this.loadedAt !== null,
|
|
117
|
+
mode: this.#unlisten ? 'notify' : 'poll',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
async stop() {
|
|
121
|
+
if (this.#timer)
|
|
122
|
+
clearInterval(this.#timer);
|
|
123
|
+
this.#timer = undefined;
|
|
124
|
+
await this.#unlisten?.().catch(() => { });
|
|
125
|
+
this.#unlisten = undefined;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=ruleset_source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleset_source.js","sourceRoot":"","sources":["../../src/ruleset_source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { FlagsAdmin } from './admin.js';
|
|
2
|
+
import type { AnalyticsBackend } from './analytics/backend.js';
|
|
3
|
+
import type { FactoryContext, FlagsConfig } from './define_config.js';
|
|
4
|
+
import { type Enricher } from './enrichers.js';
|
|
5
|
+
import { EventBuffer } from './events/buffer.js';
|
|
6
|
+
import type { BrowserTokens } from './http/browser_tokens.js';
|
|
7
|
+
import { FlagsManager } from './manager.js';
|
|
8
|
+
import { Relay } from './relay/relay.js';
|
|
9
|
+
import { type ResultsCache } from './relay/results_cache.js';
|
|
10
|
+
import { FlagsWorker } from './relay/worker.js';
|
|
11
|
+
import { type RulesetSource } from './ruleset_source.js';
|
|
12
|
+
import type { Sink } from './sinks/sink.js';
|
|
13
|
+
import { type SqlDatabase } from './sql.js';
|
|
14
|
+
import type { FlagsStore } from './stores/store.js';
|
|
15
|
+
import { type TokenSource } from './topology/token.js';
|
|
16
|
+
import type { Transport } from './transports/transport.js';
|
|
17
|
+
import { UsageCounter } from './usage.js';
|
|
18
|
+
export interface Logger {
|
|
19
|
+
info?(message: string): void;
|
|
20
|
+
warn(message: string): void;
|
|
21
|
+
error(message: string): void;
|
|
22
|
+
}
|
|
23
|
+
export type Topology = 'standalone' | 'control-plane' | 'tenant';
|
|
24
|
+
export type Role = 'all' | 'api' | 'worker';
|
|
25
|
+
/** Everything a flags deployment is made of, built from `config/flags.ts`. */
|
|
26
|
+
export interface FlagsRuntime {
|
|
27
|
+
config: FlagsConfig;
|
|
28
|
+
topology: Topology;
|
|
29
|
+
role: Role;
|
|
30
|
+
manager: FlagsManager;
|
|
31
|
+
source: RulesetSource;
|
|
32
|
+
admin?: FlagsAdmin;
|
|
33
|
+
store?: FlagsStore;
|
|
34
|
+
transport?: Transport;
|
|
35
|
+
sinks: Map<string, Sink>;
|
|
36
|
+
relay?: Relay;
|
|
37
|
+
analytics?: AnalyticsBackend;
|
|
38
|
+
resultsCache?: ResultsCache;
|
|
39
|
+
worker?: FlagsWorker;
|
|
40
|
+
buffer?: EventBuffer;
|
|
41
|
+
usage?: UsageCounter;
|
|
42
|
+
enrichers: Enricher[];
|
|
43
|
+
/** Tenant only: how it authenticates to the control-plane. */
|
|
44
|
+
token?: TokenSource;
|
|
45
|
+
/** Issues browser tokens, when `browser` is configured (set by the provider). */
|
|
46
|
+
browser?: BrowserTokens | undefined;
|
|
47
|
+
close(): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
export interface RuntimeOptions {
|
|
50
|
+
logger?: Logger;
|
|
51
|
+
/** Called after a ruleset change applied in this process (to notify browsers, etc.). */
|
|
52
|
+
onApplied?: (environment: string, version: string) => void;
|
|
53
|
+
/** Start timers (source polling, buffer, usage, in-process worker). Default `true`. */
|
|
54
|
+
start?: boolean;
|
|
55
|
+
/** Whether this process runs the in-process worker loop. Decided by the provider. */
|
|
56
|
+
runWorker?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Hold a connection for Postgres `LISTEN` (instant ruleset changes). Default `true`; the provider
|
|
59
|
+
* turns it off in ace commands and the REPL: a held connection keeps Lucid from closing its
|
|
60
|
+
* pool, so `node ace migration:run` and friends would never exit.
|
|
61
|
+
*/
|
|
62
|
+
listen?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/** Builds (and starts) the runtime. Shared by the provider, the commands and the tests. */
|
|
65
|
+
export declare function createRuntime(config: FlagsConfig, ctx: FactoryContext, options?: RuntimeOptions): Promise<FlagsRuntime>;
|
|
66
|
+
/** A database for factories, from a Lucid `Database` (or anything with `connection()`). */
|
|
67
|
+
export declare function lucidContext(db: {
|
|
68
|
+
connection(name?: string): SqlDatabase;
|
|
69
|
+
} | undefined, options?: Partial<Pick<FactoryContext, 'autoCreateSchema' | 'partitionEvents' | 'redis' | 'app'>>): FactoryContext;
|
|
70
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"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"}
|