@toa.io/extensions.chronicles 1.0.0-alpha.332 → 1.0.0-alpha.333

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 (82) hide show
  1. package/LICENSE +22 -0
  2. package/components/chronicles.encounters/manifest.toa.yaml +108 -0
  3. package/components/{chronicles.ingestion → chronicles.encounters}/operations/anonymous.js +1 -1
  4. package/components/chronicles.encounters/operations/describe.js +4 -0
  5. package/components/{chronicles.ingestion → chronicles.encounters}/operations/identified.js +1 -1
  6. package/components/{chronicles.ingestion → chronicles.encounters}/types/toa.d.ts +13 -0
  7. package/components/chronicles.queries/manifest.toa.yaml +39 -15
  8. package/components/chronicles.queries/operations/define.js +1 -1
  9. package/components/chronicles.queries/types/toa.d.ts +8 -3
  10. package/components/{chronicles.facts → chronicles.relay}/manifest.toa.yaml +14 -3
  11. package/components/chronicles.relay/operations/encounter.js +4 -0
  12. package/components/{chronicles.facts → chronicles.relay}/operations/record.js +1 -1
  13. package/components/{chronicles.facts → chronicles.relay}/types/toa.d.ts +5 -0
  14. package/guides/clickhouse.md +19 -0
  15. package/guides/log.md +52 -0
  16. package/package.json +8 -4
  17. package/readme.md +459 -142
  18. package/store/clickhouse.scope.sql +29 -0
  19. package/store/clickhouse.sql +99 -0
  20. package/transpiled/Client.d.ts +19 -6
  21. package/transpiled/Client.js +89 -37
  22. package/transpiled/Client.js.map +1 -1
  23. package/transpiled/Factory.d.ts +13 -5
  24. package/transpiled/Factory.js +32 -23
  25. package/transpiled/Factory.js.map +1 -1
  26. package/transpiled/Provider.d.ts +76 -25
  27. package/transpiled/Provider.js.map +1 -1
  28. package/transpiled/Publisher.d.ts +50 -0
  29. package/transpiled/Publisher.js +169 -0
  30. package/transpiled/Publisher.js.map +1 -0
  31. package/transpiled/Reader.d.ts +15 -3
  32. package/transpiled/Reader.js +98 -14
  33. package/transpiled/Reader.js.map +1 -1
  34. package/transpiled/Recorder.d.ts +21 -11
  35. package/transpiled/Recorder.js +49 -24
  36. package/transpiled/Recorder.js.map +1 -1
  37. package/transpiled/Relay.d.ts +14 -0
  38. package/transpiled/Relay.js +27 -0
  39. package/transpiled/Relay.js.map +1 -0
  40. package/transpiled/Sender.d.ts +8 -4
  41. package/transpiled/Sender.js +27 -10
  42. package/transpiled/Sender.js.map +1 -1
  43. package/transpiled/Service.d.ts +26 -0
  44. package/transpiled/Service.js +70 -0
  45. package/transpiled/Service.js.map +1 -0
  46. package/transpiled/agent.d.ts +16 -0
  47. package/transpiled/agent.js +48 -0
  48. package/transpiled/agent.js.map +1 -0
  49. package/transpiled/clickhouse/Client.d.ts +5 -8
  50. package/transpiled/clickhouse/Client.js +12 -14
  51. package/transpiled/clickhouse/Client.js.map +1 -1
  52. package/transpiled/clickhouse/Provider.d.ts +20 -18
  53. package/transpiled/clickhouse/Provider.js +97 -72
  54. package/transpiled/clickhouse/Provider.js.map +1 -1
  55. package/transpiled/clickhouse/ddl.d.ts +3 -20
  56. package/transpiled/clickhouse/ddl.js +6 -79
  57. package/transpiled/clickhouse/ddl.js.map +1 -1
  58. package/transpiled/clickhouse/views.d.ts +11 -0
  59. package/transpiled/clickhouse/views.js +97 -0
  60. package/transpiled/clickhouse/views.js.map +1 -0
  61. package/transpiled/contract.d.ts +12 -0
  62. package/transpiled/contract.js +58 -0
  63. package/transpiled/contract.js.map +1 -0
  64. package/transpiled/index.d.ts +9 -3
  65. package/transpiled/settings.d.ts +6 -4
  66. package/transpiled/settings.js +27 -14
  67. package/transpiled/settings.js.map +1 -1
  68. package/transpiled/store.d.ts +3 -3
  69. package/transpiled/store.js +3 -3
  70. package/transpiled/store.js.map +1 -1
  71. package/components/chronicles.ingestion/manifest.toa.yaml +0 -60
  72. package/transpiled/Facts.d.ts +0 -9
  73. package/transpiled/Facts.js +0 -16
  74. package/transpiled/Facts.js.map +0 -1
  75. package/transpiled/Scribe.d.ts +0 -25
  76. package/transpiled/Scribe.js +0 -61
  77. package/transpiled/Scribe.js.map +0 -1
  78. package/transpiled/Writer.d.ts +0 -14
  79. package/transpiled/Writer.js +0 -50
  80. package/transpiled/Writer.js.map +0 -1
  81. /package/components/{chronicles.facts → chronicles.encounters}/types/index.d.ts +0 -0
  82. /package/components/{chronicles.ingestion → chronicles.relay}/types/index.d.ts +0 -0
@@ -0,0 +1,58 @@
1
+ /**
2
+ * What of a payload is written: the declared properties, at every depth, and nothing else. A
3
+ * value that is not of its declared type is a payload the contract does not admit, which throws a
4
+ * `Mismatch` naming where; `null` is admitted for any property, and an absent one stays absent.
5
+ */
6
+ export function project(payload, properties, path = '') {
7
+ const projected = {};
8
+ for (const [name, property] of Object.entries(properties)) {
9
+ const value = payload[name];
10
+ if (value === undefined)
11
+ continue;
12
+ projected[name] = fit(value, property, path === '' ? name : `${path}.${name}`);
13
+ }
14
+ return projected;
15
+ }
16
+ function fit(value, property, path) {
17
+ if (value === null)
18
+ return null;
19
+ switch (property.type) {
20
+ case 'string':
21
+ if (typeof value !== 'string')
22
+ throw new Mismatch(path, property);
23
+ if (property.enum !== undefined && !property.enum.includes(value))
24
+ throw new Mismatch(path, property);
25
+ return value;
26
+ case 'integer':
27
+ if (!Number.isInteger(value))
28
+ throw new Mismatch(path, property);
29
+ return value;
30
+ case 'number':
31
+ if (typeof value !== 'number' || !Number.isFinite(value))
32
+ throw new Mismatch(path, property);
33
+ return value;
34
+ case 'boolean':
35
+ if (typeof value !== 'boolean')
36
+ throw new Mismatch(path, property);
37
+ return value;
38
+ case 'object':
39
+ if (typeof value !== 'object' || Array.isArray(value))
40
+ throw new Mismatch(path, property);
41
+ return project(value, property.properties ?? {}, path);
42
+ case 'array':
43
+ if (!Array.isArray(value))
44
+ throw new Mismatch(path, property);
45
+ return value.map((item, index) => fit(item, property.items, `${path}[${index}]`));
46
+ }
47
+ }
48
+ /** A payload's value at `path` is not of the type its contract declares. */
49
+ export class Mismatch extends Error {
50
+ path;
51
+ constructor(path, property) {
52
+ super(property.enum === undefined
53
+ ? `'${path}' is not of the type '${property.type}'`
54
+ : `'${path}' is not one of ${property.enum.map((value) => `'${value}'`).join(', ')}`);
55
+ this.path = path;
56
+ }
57
+ }
58
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../source/contract.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,14 @@ export { Factory } from './Factory.ts';
2
2
  /** `context.chronicles` of a component that declares `chronicles`. */
3
3
  export interface Chronicles {
4
4
  /**
5
- * Writes a fact that changes no state to the log, under `<component>.<name>`. Resolves once the
6
- * broker has it; nothing retries it.
5
+ * Writes a fact that changes no state to the log, under `<component>.<name>`, of which what the
6
+ * component declares of it is written. Resolves once the broker has it; nothing retries it.
7
+ * Throws for a name the component does not declare, or a payload its declaration does not admit.
7
8
  */
8
- send(name: string, payload?: object): Promise<void>;
9
+ send(name: string, payload?: object, options?: Options): Promise<void>;
10
+ }
11
+ /** What a fact is said to be of: the operation knows whose it is, the extension does not. */
12
+ export interface Options {
13
+ /** the identity the fact is of */
14
+ identity?: string;
9
15
  }
@@ -1,11 +1,13 @@
1
1
  import type { Settings } from '@toa.io/definitions/extensions.chronicles';
2
- /** Where the log is kept and what it is kept of, as the service is deployed with them. */
2
+ /** Where the log is published and read, and what it is kept of, as the service is deployed with them. */
3
3
  export declare function settings(): Settings;
4
- /** The user the store is provisioned as, and the password of the reader it creates. */
4
+ /** The users of the broker the rows are published to, and of the store they are read from. */
5
5
  export declare function credentials(): Credentials;
6
6
  export interface Credentials {
7
+ broker: User;
8
+ store: User;
9
+ }
10
+ export interface User {
7
11
  username: string;
8
12
  password: string;
9
- /** the password of the reader */
10
- reader: string;
11
13
  }
@@ -1,6 +1,6 @@
1
1
  import { environment } from '@toa.io/generic';
2
- import { SETTINGS } from '@toa.io/definitions/extensions.chronicles';
3
- /** Where the log is kept and what it is kept of, as the service is deployed with them. */
2
+ import { KEYS, SETTINGS } from '@toa.io/definitions/extensions.chronicles';
3
+ /** Where the log is published and read, and what it is kept of, as the service is deployed with them. */
4
4
  export function settings() {
5
5
  const value = environment.get(SETTINGS);
6
6
  if (value !== undefined)
@@ -9,27 +9,40 @@ export function settings() {
9
9
  return DEV;
10
10
  throw new Error(`${SETTINGS} is not set, so nothing says where the log is kept.`);
11
11
  }
12
- /** The user the store is provisioned as, and the password of the reader it creates. */
12
+ /** The users of the broker the rows are published to, and of the store they are read from. */
13
13
  export function credentials() {
14
- const [username, password, reader] = KEYS.map((key) => environment.get(`${SETTINGS}_STORE_${key}`));
15
- if (username !== undefined && password !== undefined && reader !== undefined)
16
- return { username, password, reader };
14
+ const [brokerUsername, brokerPassword, storeUsername, storePassword] = KEYS.map((key) => environment.get(`${SETTINGS}_${key.toUpperCase()}`));
15
+ if (brokerUsername !== undefined &&
16
+ brokerPassword !== undefined &&
17
+ storeUsername !== undefined &&
18
+ storePassword !== undefined)
19
+ return {
20
+ broker: { username: brokerUsername, password: brokerPassword },
21
+ store: { username: storeUsername, password: storePassword }
22
+ };
23
+ // the development stack's broker, and the context's user of its store, as the reference setup
24
+ // makes one
17
25
  if (dev())
18
- return { username: 'developer', password: 'secret', reader: 'secret' };
19
- throw new Error(`${SETTINGS}_STORE_{USERNAME,PASSWORD,READER} are not all set.`);
26
+ return {
27
+ broker: { username: 'developer', password: 'secret' },
28
+ store: { username: environment.scope(), password: 'secret' }
29
+ };
30
+ throw new Error(`${SETTINGS}_{${KEYS.join(',').toUpperCase()}} are not all set.`);
20
31
  }
21
32
  function dev() {
22
33
  return environment.get('TOA_DEV') === '1';
23
34
  }
24
- const KEYS = ['USERNAME', 'PASSWORD', 'READER'];
25
35
  // Toa's own development stack is not on the conventional ports, which the applications built on
26
36
  // Toa are on. See CONTRIBUTING.md.
27
37
  const DEV = {
28
- store: { provider: 'clickhouse', url: 'http://localhost:31030/chronicles' },
29
- ingest: true,
38
+ broker: 'amqp://localhost:31010',
39
+ store: { provider: 'clickhouse', url: 'http://localhost:31030' },
40
+ encounters: true,
30
41
  ip: 'truncated',
31
- events: [],
32
- states: [],
33
- identities: {}
42
+ events: {},
43
+ states: {},
44
+ facts: {},
45
+ identities: {},
46
+ timestamps: {}
34
47
  };
35
48
  //# sourceMappingURL=settings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../source/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAA;AAGpE,0FAA0F;AAC1F,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAEvC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAa,CAAA;IAE7D,IAAI,GAAG,EAAE;QAAE,OAAO,GAAG,CAAA;IAErB,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,qDAAqD,CAAC,CAAA;AACnF,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACpD,WAAW,CAAC,GAAG,CAAC,GAAG,QAAQ,UAAU,GAAG,EAAE,CAAC,CAC5C,CAAA;IAED,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;QAC1E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;IAEvC,IAAI,GAAG,EAAE;QAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;IAEjF,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,oDAAoD,CAAC,CAAA;AAClF,CAAC;AAUD,SAAS,GAAG;IACV,OAAO,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG,CAAA;AAC3C,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;AAE/C,gGAAgG;AAChG,mCAAmC;AACnC,MAAM,GAAG,GAAa;IACpB,KAAK,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,mCAAmC,EAAE;IAC3E,MAAM,EAAE,IAAI;IACZ,EAAE,EAAE,WAAW;IACf,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,EAAE;IACV,UAAU,EAAE,EAAE;CACf,CAAA"}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../source/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAA;AAG1E,yGAAyG;AACzG,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAEvC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAa,CAAA;IAE7D,IAAI,GAAG,EAAE;QAAE,OAAO,GAAG,CAAA;IAErB,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,qDAAqD,CAAC,CAAA;AACnF,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACtF,WAAW,CAAC,GAAG,CAAC,GAAG,QAAQ,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CACpD,CAAA;IAED,IACE,cAAc,KAAK,SAAS;QAC5B,cAAc,KAAK,SAAS;QAC5B,aAAa,KAAK,SAAS;QAC3B,aAAa,KAAK,SAAS;QAE3B,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE;YAC9D,KAAK,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE;SAC5D,CAAA;IAEH,8FAA8F;IAC9F,YAAY;IACZ,IAAI,GAAG,EAAE;QACP,OAAO;YACL,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE;YACrD,KAAK,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;SAC7D,CAAA;IAEH,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAA;AACnF,CAAC;AAYD,SAAS,GAAG;IACV,OAAO,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG,CAAA;AAC3C,CAAC;AAED,gGAAgG;AAChG,mCAAmC;AACnC,MAAM,GAAG,GAAa;IACpB,MAAM,EAAE,wBAAwB;IAChC,KAAK,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,wBAAwB,EAAE;IAChE,UAAU,EAAE,IAAI;IAChB,EAAE,EAAE,WAAW;IACf,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,EAAE;CACf,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import type { Provider } from './Provider.ts';
2
- import type { Credentials } from './settings.ts';
2
+ import type { User } from './settings.ts';
3
3
  import type { Settings } from '@toa.io/definitions/extensions.chronicles';
4
- /** The provider the annotation names. */
5
- export declare function provider(settings: Settings, credentials: Credentials): Provider;
4
+ /** The provider the annotation names, read as the context's user of it. */
5
+ export declare function provider(settings: Settings, user: User, scope: string): Provider;
@@ -1,9 +1,9 @@
1
1
  import { ClickHouseProvider } from './clickhouse/Provider.js';
2
- /** The provider the annotation names. */
3
- export function provider(settings, credentials) {
2
+ /** The provider the annotation names, read as the context's user of it. */
3
+ export function provider(settings, user, scope) {
4
4
  switch (settings.store.provider) {
5
5
  case 'clickhouse':
6
- return new ClickHouseProvider(settings.store.url, credentials, settings.retention);
6
+ return new ClickHouseProvider(settings.store.url, user, scope);
7
7
  default:
8
8
  throw new Error(`Chronicles have no store '${String(settings.store.provider)}'`);
9
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../source/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAK7D,yCAAyC;AACzC,MAAM,UAAU,QAAQ,CAAC,QAAkB,EAAE,WAAwB;IACnE,QAAQ,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,KAAK,YAAY;YACf,OAAO,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;QACpF;YACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IACpF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../source/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAK7D,2EAA2E;AAC3E,MAAM,UAAU,QAAQ,CAAC,QAAkB,EAAE,IAAU,EAAE,KAAa;IACpE,QAAQ,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,KAAK,YAAY;YACf,OAAO,IAAI,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;QAChE;YACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IACpF,CAAC;AACH,CAAC"}
@@ -1,60 +0,0 @@
1
- namespace: chronicles
2
- name: ingestion
3
-
4
- # The extension writes what this component is sent to the log, under `agent.`
5
- chronicles: ~
6
-
7
- operations:
8
- anonymous:
9
- type: effect
10
- input: &batch
11
- description: >
12
- `{ events }`, at most 100 of them, each `{ id, name, time, payload? }`, and the client's
13
- `ip` and `country`, which the gateway puts in; as JSON, or as the form
14
- `navigator.sendBeacon` sends, whose `events` is their JSON, which the extension parses
15
- and checks
16
- type: object
17
- output: &accepted
18
- type: object
19
- properties:
20
- status:
21
- type: integer
22
- accepted:
23
- type: integer
24
- errors: &errors [INVALID, OVERSIZED]
25
- identified:
26
- type: effect
27
- input: *batch
28
- output: *accepted
29
- errors: *errors
30
-
31
- exposition:
32
- isolated: true
33
- /:
34
- POST:
35
- anonymous: true
36
- map:ip: ip
37
- map:country: country
38
- io:throttle:
39
- key: [ip]
40
- requests: 60
41
- interval: 60
42
- io:status: status
43
- io:output: [status, accepted]
44
- help:method: null
45
- endpoint: anonymous
46
- /:identity:
47
- POST:
48
- auth:id: identity
49
- map:segments:
50
- identity: identity
51
- map:ip: ip
52
- map:country: country
53
- io:throttle:
54
- key: [identity]
55
- requests: 60
56
- interval: 60
57
- io:status: status
58
- io:output: [status, accepted]
59
- help:method: null
60
- endpoint: identified
@@ -1,9 +0,0 @@
1
- import { Connector } from '@toa.io/core';
2
- import type { Writer } from './Writer.ts';
3
- /** What `chronicles.facts` writes a fact a component sent through. */
4
- export declare class Facts extends Connector {
5
- readonly name = "chronicles";
6
- private readonly writer;
7
- constructor(writer: () => Writer);
8
- invoke(method: string, ...args: any[]): Promise<void>;
9
- }
@@ -1,16 +0,0 @@
1
- import { Connector, exceptions } from '@toa.io/core';
2
- /** What `chronicles.facts` writes a fact a component sent through. */
3
- export class Facts extends Connector {
4
- name = 'chronicles';
5
- writer;
6
- constructor(writer) {
7
- super();
8
- this.writer = writer;
9
- }
10
- async invoke(method, ...args) {
11
- if (method !== 'record')
12
- throw new exceptions.MisuseException(`Chronicles have no '${method}'`);
13
- await this.writer().write([args[0]]);
14
- }
15
- }
16
- //# sourceMappingURL=Facts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Facts.js","sourceRoot":"","sources":["../source/Facts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAIpD,sEAAsE;AACtE,MAAM,OAAO,KAAM,SAAQ,SAAS;IAClB,IAAI,GAAG,YAAY,CAAA;IAElB,MAAM,CAAc;IAErC,YAAmB,MAAoB;QACrC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,GAAG,IAAW;QAChD,IAAI,MAAM,KAAK,QAAQ;YACrB,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,uBAAuB,MAAM,GAAG,CAAC,CAAA;QAExE,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAQ,CAAC,CAAC,CAAA;IAC7C,CAAC;CACF"}
@@ -1,25 +0,0 @@
1
- import { Connector } from '@toa.io/core';
2
- import type { Provider } from './Provider.ts';
3
- import type { Writer } from './Writer.ts';
4
- import type { Settings } from '@toa.io/definitions/extensions.chronicles';
5
- import type { extensions } from '@toa.io/core/types';
6
- /**
7
- * The extension's own service: the store provisioned, then a consumer of every event the log is
8
- * kept of — one group for every replica, so each event is written once — and the components it
9
- * ships: the queries, the facts, and the client route where the annotation asks for it.
10
- */
11
- export declare class Scribe extends Connector {
12
- private readonly host;
13
- private readonly settings;
14
- private readonly provider;
15
- private readonly writer;
16
- constructor(host: extensions.Host, settings: Settings, provider: Provider, writer: Writer);
17
- protected open(): Promise<void>;
18
- }
19
- /** The components this extension ships, which run inside its own service. */
20
- export declare function components(): Components;
21
- interface Components {
22
- labels: string[];
23
- paths: string[];
24
- }
25
- export {};
@@ -1,61 +0,0 @@
1
- import { readdirSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
- import { Connector } from '@toa.io/core';
4
- import { INGESTION, NAMESPACE, SERVICE } from '@toa.io/definitions/extensions.chronicles';
5
- import { Recorder } from './Recorder.js';
6
- /**
7
- * The extension's own service: the store provisioned, then a consumer of every event the log is
8
- * kept of — one group for every replica, so each event is written once — and the components it
9
- * ships: the queries, the facts, and the client route where the annotation asks for it.
10
- */
11
- export class Scribe extends Connector {
12
- host;
13
- settings;
14
- provider;
15
- writer;
16
- // eslint-disable-next-line max-params
17
- constructor(host, settings, provider, writer) {
18
- super();
19
- this.host = host;
20
- this.settings = settings;
21
- this.provider = provider;
22
- this.writer = writer;
23
- }
24
- async open() {
25
- await this.provider.provision();
26
- const consumed = [
27
- ...this.settings.events.map((label) => [label, 'event']),
28
- ...this.settings.states.map((label) => [label, 'state'])
29
- ];
30
- for (const [label, kind] of consumed) {
31
- // an event that is both a row and a state is two consumers, each of a group of its own
32
- const group = kind === 'state' ? `${GROUP}.states` : GROUP;
33
- const component = label.slice(0, label.lastIndexOf('.'));
34
- const identity = this.settings.identities[component] ?? null;
35
- const recorder = new Recorder(label, kind, identity, this.writer);
36
- const consumer = await this.host.receive(label, group, recorder);
37
- this.depends(consumer);
38
- await consumer.connect();
39
- }
40
- const composition = await this.host.composition(paths(this.settings));
41
- this.depends(composition);
42
- await composition.connect();
43
- }
44
- }
45
- /** The components this extension ships, which run inside its own service. */
46
- export function components() {
47
- const labels = [];
48
- const paths = [];
49
- for (const entry of readdirSync(ROOT, { withFileTypes: true }))
50
- if (entry.isDirectory()) {
51
- labels.push(entry.name.replace('.', '-'));
52
- paths.push(resolve(ROOT, entry.name));
53
- }
54
- return { labels, paths };
55
- }
56
- function paths(settings) {
57
- return components().paths.filter((path) => settings.ingest || !path.endsWith(`${NAMESPACE}.${INGESTION}`));
58
- }
59
- const ROOT = resolve(import.meta.dirname, '../components/');
60
- const GROUP = `${NAMESPACE}.${SERVICE}`;
61
- //# sourceMappingURL=Scribe.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Scribe.js","sourceRoot":"","sources":["../source/Scribe.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- import type { Provider, Row, State } from './Provider.ts';
2
- /**
3
- * Rows to the provider in batches: what arrives within a moment, or until a batch is full, is
4
- * one write. Each caller is answered when the write its rows went in is, so a delivery is
5
- * acknowledged once what it carried is kept, and is delivered again where it was not.
6
- */
7
- export declare class Writer {
8
- private readonly provider;
9
- private pending;
10
- constructor(provider: Provider);
11
- write(rows: Row[], states?: State[]): Promise<void>;
12
- private open;
13
- private flush;
14
- }
@@ -1,50 +0,0 @@
1
- import { console } from 'openspan';
2
- /**
3
- * Rows to the provider in batches: what arrives within a moment, or until a batch is full, is
4
- * one write. Each caller is answered when the write its rows went in is, so a delivery is
5
- * acknowledged once what it carried is kept, and is delivered again where it was not.
6
- */
7
- export class Writer {
8
- provider;
9
- pending = null;
10
- constructor(provider) {
11
- this.provider = provider;
12
- }
13
- async write(rows, states = []) {
14
- const batch = (this.pending ??= this.open());
15
- batch.rows.push(...rows);
16
- batch.states.push(...states);
17
- if (batch.rows.length + batch.states.length >= SIZE)
18
- this.flush(batch);
19
- await batch.written;
20
- }
21
- open() {
22
- let settle;
23
- const written = new Promise((resolve, reject) => {
24
- settle = (error) => (error === undefined ? resolve() : reject(error));
25
- });
26
- const batch = { rows: [], states: [], written, settle, timer: null };
27
- batch.timer = setTimeout(() => this.flush(batch), WAIT);
28
- return batch;
29
- }
30
- flush(batch) {
31
- if (this.pending === batch)
32
- this.pending = null;
33
- if (batch.timer === null)
34
- return;
35
- clearTimeout(batch.timer);
36
- batch.timer = null;
37
- this.provider.write(batch.rows, batch.states).then(() => batch.settle(), (error) => {
38
- console.warn('Chronicles failed to write', {
39
- rows: batch.rows.length,
40
- states: batch.states.length,
41
- error: error instanceof Error ? error.message : String(error)
42
- });
43
- batch.settle(error);
44
- });
45
- }
46
- }
47
- /** rows that make a batch full, and milliseconds a batch waits for more */
48
- const SIZE = 1000;
49
- const WAIT = 500;
50
- //# sourceMappingURL=Writer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Writer.js","sourceRoot":"","sources":["../source/Writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAGlC;;;;GAIG;AACH,MAAM,OAAO,MAAM;IACA,QAAQ,CAAU;IAC3B,OAAO,GAAiB,IAAI,CAAA;IAEpC,YAAmB,QAAkB;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,IAAW,EAAE,MAAM,GAAY,EAAE;QAClD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAE5C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QACxB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;QAE5B,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEtE,MAAM,KAAK,CAAC,OAAO,CAAA;IACrB,CAAC;IAEO,IAAI;QACV,IAAI,MAAkC,CAAA;QAEtC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpD,MAAM,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACvE,CAAC,CAAC,CAAA;QAEF,MAAM,KAAK,GAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;QAE3E,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;QAEvD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,KAAK,CAAC,KAAY;QACxB,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QAE/C,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI;YAAE,OAAM;QAEhC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACzB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAElB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAChD,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EACpB,CAAC,KAAc,EAAE,EAAE;YACjB,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE;gBACzC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM;gBACvB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;gBAC3B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAA;YAEF,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC,CACF,CAAA;IACH,CAAC;CACF;AAUD,2EAA2E;AAC3E,MAAM,IAAI,GAAG,IAAI,CAAA;AACjB,MAAM,IAAI,GAAG,GAAG,CAAA"}