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

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 (67) hide show
  1. package/components/chronicles.facts/manifest.toa.yaml +32 -0
  2. package/components/chronicles.facts/operations/record.js +4 -0
  3. package/components/chronicles.facts/types/index.d.ts +3 -0
  4. package/components/chronicles.facts/types/toa.d.ts +19 -0
  5. package/components/chronicles.ingestion/manifest.toa.yaml +60 -0
  6. package/components/chronicles.ingestion/operations/anonymous.js +4 -0
  7. package/components/chronicles.ingestion/operations/identified.js +4 -0
  8. package/components/chronicles.ingestion/types/index.d.ts +3 -0
  9. package/components/chronicles.ingestion/types/toa.d.ts +23 -0
  10. package/components/chronicles.queries/manifest.toa.yaml +115 -0
  11. package/components/chronicles.queries/operations/define.js +3 -0
  12. package/components/chronicles.queries/operations/describe.js +3 -0
  13. package/components/chronicles.queries/operations/drop.js +3 -0
  14. package/components/chronicles.queries/operations/query.js +3 -0
  15. package/components/chronicles.queries/types/index.d.ts +3 -0
  16. package/components/chronicles.queries/types/toa.d.ts +44 -0
  17. package/package.json +35 -4
  18. package/readme.md +369 -0
  19. package/transpiled/Client.d.ts +19 -0
  20. package/transpiled/Client.js +121 -0
  21. package/transpiled/Client.js.map +1 -0
  22. package/transpiled/Factory.d.ts +16 -0
  23. package/transpiled/Factory.js +53 -0
  24. package/transpiled/Factory.js.map +1 -0
  25. package/transpiled/Facts.d.ts +9 -0
  26. package/transpiled/Facts.js +16 -0
  27. package/transpiled/Facts.js.map +1 -0
  28. package/transpiled/Provider.d.ts +91 -0
  29. package/transpiled/Provider.js +4 -0
  30. package/transpiled/Provider.js.map +1 -0
  31. package/transpiled/Reader.d.ts +16 -0
  32. package/transpiled/Reader.js +82 -0
  33. package/transpiled/Reader.js.map +1 -0
  34. package/transpiled/Recorder.d.ts +28 -0
  35. package/transpiled/Recorder.js +82 -0
  36. package/transpiled/Recorder.js.map +1 -0
  37. package/transpiled/Scribe.d.ts +25 -0
  38. package/transpiled/Scribe.js +61 -0
  39. package/transpiled/Scribe.js.map +1 -0
  40. package/transpiled/Sender.d.ts +21 -0
  41. package/transpiled/Sender.js +69 -0
  42. package/transpiled/Sender.js.map +1 -0
  43. package/transpiled/Writer.d.ts +14 -0
  44. package/transpiled/Writer.js +50 -0
  45. package/transpiled/Writer.js.map +1 -0
  46. package/transpiled/address.d.ts +7 -0
  47. package/transpiled/address.js +27 -0
  48. package/transpiled/address.js.map +1 -0
  49. package/transpiled/clickhouse/Client.d.ts +38 -0
  50. package/transpiled/clickhouse/Client.js +73 -0
  51. package/transpiled/clickhouse/Client.js.map +1 -0
  52. package/transpiled/clickhouse/Provider.d.ts +33 -0
  53. package/transpiled/clickhouse/Provider.js +144 -0
  54. package/transpiled/clickhouse/Provider.js.map +1 -0
  55. package/transpiled/clickhouse/ddl.d.ts +26 -0
  56. package/transpiled/clickhouse/ddl.js +88 -0
  57. package/transpiled/clickhouse/ddl.js.map +1 -0
  58. package/transpiled/index.d.ts +9 -0
  59. package/transpiled/index.js +2 -0
  60. package/transpiled/index.js.map +1 -0
  61. package/transpiled/settings.d.ts +11 -0
  62. package/transpiled/settings.js +35 -0
  63. package/transpiled/settings.js.map +1 -0
  64. package/transpiled/store.d.ts +5 -0
  65. package/transpiled/store.js +11 -0
  66. package/transpiled/store.js.map +1 -0
  67. package/README.md +0 -3
@@ -0,0 +1,32 @@
1
+ namespace: chronicles
2
+ name: facts
3
+
4
+ # The extension writes what this component is sent to the log.
5
+ chronicles: ~
6
+
7
+ operations:
8
+ record:
9
+ type: effect
10
+ input:
11
+ description: A fact a component sent, as the row it is written as
12
+ type: object
13
+ properties:
14
+ id:
15
+ type: string
16
+ label:
17
+ type: string
18
+ component:
19
+ type: string
20
+ time:
21
+ type: integer
22
+ entity:
23
+ type: "null"
24
+ version:
25
+ type: "null"
26
+ identity:
27
+ type: [string, "null"]
28
+ trace:
29
+ type: [string, "null"]
30
+ payload:
31
+ type: object
32
+ required: [id, label, component, time, payload]
@@ -0,0 +1,4 @@
1
+ // a fact a component sent with `context.chronicles.send`, written by the extension
2
+ export async function effect(input, context) {
3
+ await context.chronicles.record(input)
4
+ }
@@ -0,0 +1,3 @@
1
+ export * from './toa.d.ts'
2
+
3
+ // What a manifest does not state belongs here, and every run keeps it.
@@ -0,0 +1,19 @@
1
+ // Written by `toa types`. Every run rewrites it.
2
+ // What a manifest does not state belongs in a file of your own.
3
+
4
+
5
+ export type RecordInput = {
6
+ id: string
7
+ label: string
8
+ component: string
9
+ time: number
10
+ entity?: null
11
+ version?: null
12
+ identity?: string | null
13
+ trace?: string | null
14
+ payload: Record<string, unknown>
15
+ }
16
+
17
+ export interface Component {
18
+ record: (request: { input: RecordInput, task?: boolean }) => Promise<unknown>
19
+ }
@@ -0,0 +1,60 @@
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
@@ -0,0 +1,4 @@
1
+ // what anyone sent, checked and written by the extension
2
+ export async function effect(input, context) {
3
+ return await context.chronicles.ingest(input, null)
4
+ }
@@ -0,0 +1,4 @@
1
+ // what a caller the gateway verified sent, written as that identity's
2
+ export async function effect(input, context) {
3
+ return await context.chronicles.ingest(input, input.identity)
4
+ }
@@ -0,0 +1,3 @@
1
+ export * from './toa.d.ts'
2
+
3
+ // What a manifest does not state belongs here, and every run keeps it.
@@ -0,0 +1,23 @@
1
+ // Written by `toa types`. Every run rewrites it.
2
+ // What a manifest does not state belongs in a file of your own.
3
+
4
+ import type { CodedError } from '@toa.io/core/types'
5
+
6
+ export type AnonymousInput = Record<string, unknown>
7
+
8
+ export type AnonymousOutput = {
9
+ status?: number
10
+ accepted?: number
11
+ }
12
+
13
+ export type IdentifiedInput = Record<string, unknown>
14
+
15
+ export type IdentifiedOutput = {
16
+ status?: number
17
+ accepted?: number
18
+ }
19
+
20
+ export interface Component {
21
+ anonymous: (request: { input: AnonymousInput, task?: boolean }) => Promise<AnonymousOutput | CodedError<"INVALID" | "OVERSIZED">>
22
+ identified: (request: { input: IdentifiedInput, task?: boolean }) => Promise<IdentifiedOutput | CodedError<"INVALID" | "OVERSIZED">>
23
+ }
@@ -0,0 +1,115 @@
1
+ namespace: chronicles
2
+ name: queries
3
+
4
+ # The extension puts the log's reader on this component.
5
+ chronicles: ~
6
+
7
+ operations:
8
+ describe:
9
+ type: computation
10
+ output:
11
+ type: object
12
+ properties:
13
+ dialect:
14
+ description: What a query is written in
15
+ type: string
16
+ labels:
17
+ type: array
18
+ states:
19
+ type: array
20
+ views:
21
+ type: array
22
+ query:
23
+ type: computation
24
+ input:
25
+ type: object
26
+ properties:
27
+ sql:
28
+ description: One statement over the log, in the dialect `describe` names
29
+ type: string
30
+ minLength: 1
31
+ maxLength: 65536
32
+ required: [sql]
33
+ output:
34
+ type: object
35
+ properties:
36
+ columns:
37
+ type: array
38
+ rows:
39
+ type: array
40
+ truncated:
41
+ type: boolean
42
+ errors: [REFUSED]
43
+ define:
44
+ type: effect
45
+ input:
46
+ type: object
47
+ properties:
48
+ name: &name
49
+ description: The view's name, which is what a query reads it by
50
+ type: string
51
+ pattern: ^[a-z][a-z0-9_]{0,62}$
52
+ sql:
53
+ description: The statement the view is, one a query could run
54
+ type: string
55
+ minLength: 1
56
+ maxLength: 65536
57
+ refresh:
58
+ description: Seconds between computations of a materialized view; absent, a plain view
59
+ type: integer
60
+ minimum: 3600
61
+ required: [name, sql]
62
+ errors: [REFUSED, RESERVED, EXHAUSTED]
63
+ drop:
64
+ type: effect
65
+ input:
66
+ type: object
67
+ properties:
68
+ name: *name
69
+ required: [name]
70
+ errors: [NOT_FOUND]
71
+
72
+ exposition:
73
+ isolated: true
74
+ /:
75
+ auth:role: system:chronicles:query
76
+ mcp:tool: true
77
+ GET:
78
+ help:method:
79
+ title: What the log holds
80
+ description: >
81
+ The dialect queries are written in; the labels of `events`, with how many rows each
82
+ has, the first and last time of them and the fields their payloads have; the
83
+ components with a state in `states`, with how many entities each has and the fields
84
+ of the state; and the views defined over the log.
85
+ io:output: true
86
+ endpoint: describe
87
+ POST:
88
+ help:method:
89
+ title: Query the log
90
+ description: >
91
+ One statement, in the dialect `chronicles.queries.GET` names, over `events`, a row
92
+ for everything that happened (id, label, component, time, received, entity, version,
93
+ trace, payload), `states`, each entity as it stands (component, entity, version, time,
94
+ received, payload), and the views. At most 30 seconds and 10000 rows; at the rows,
95
+ `truncated` is true.
96
+ io:output: true
97
+ endpoint: query
98
+ /views/:name:
99
+ auth:role: system:chronicles:views
100
+ mcp:tool: true
101
+ PUT:
102
+ help:method:
103
+ title: Define a view
104
+ description: >
105
+ A view over the log, by a statement a query could run. Without `refresh` it is computed
106
+ when it is read; with `refresh`, in seconds and at least 3600, it is computed on that
107
+ cycle and read as a table. Defining a name again replaces the view.
108
+ help:route:
109
+ name: The view's name
110
+ endpoint: define
111
+ DELETE:
112
+ help:method: Drop a view
113
+ help:route:
114
+ name: The view's name
115
+ endpoint: drop
@@ -0,0 +1,3 @@
1
+ export async function effect(input, context) {
2
+ return await context.chronicles.define(input.name, input.sql, input.refresh)
3
+ }
@@ -0,0 +1,3 @@
1
+ export async function computation(_, context) {
2
+ return await context.chronicles.describe()
3
+ }
@@ -0,0 +1,3 @@
1
+ export async function effect(input, context) {
2
+ return await context.chronicles.drop(input.name)
3
+ }
@@ -0,0 +1,3 @@
1
+ export async function computation(input, context) {
2
+ return await context.chronicles.query(input.sql)
3
+ }
@@ -0,0 +1,3 @@
1
+ export * from './toa.d.ts'
2
+
3
+ // What a manifest does not state belongs here, and every run keeps it.
@@ -0,0 +1,44 @@
1
+ // Written by `toa types`. Every run rewrites it.
2
+ // What a manifest does not state belongs in a file of your own.
3
+
4
+ import type { CodedError } from '@toa.io/core/types'
5
+
6
+ export type DescribeOutput = {
7
+ /** What a query is written in */
8
+ dialect?: string
9
+ labels?: unknown[]
10
+ states?: unknown[]
11
+ views?: unknown[]
12
+ }
13
+
14
+ export type QueryInput = {
15
+ /** One statement over the log, in the dialect `describe` names */
16
+ sql: string
17
+ }
18
+
19
+ export type QueryOutput = {
20
+ columns?: unknown[]
21
+ rows?: unknown[]
22
+ truncated?: boolean
23
+ }
24
+
25
+ export type DefineInput = {
26
+ /** The view's name, which is what a query reads it by */
27
+ name: string
28
+ /** The statement the view is, one a query could run */
29
+ sql: string
30
+ /** Seconds between computations of a materialized view; absent, a plain view */
31
+ refresh?: number
32
+ }
33
+
34
+ export type DropInput = {
35
+ /** The view's name, which is what a query reads it by */
36
+ name: string
37
+ }
38
+
39
+ export interface Component {
40
+ describe: (request: { input?: null, task?: boolean }) => Promise<DescribeOutput>
41
+ query: (request: { input: QueryInput, task?: boolean }) => Promise<QueryOutput | CodedError<"REFUSED">>
42
+ define: (request: { input: DefineInput, task?: boolean }) => Promise<{} | null | undefined | CodedError<"REFUSED" | "RESERVED" | "EXHAUSTED">>
43
+ drop: (request: { input: DropInput, task?: boolean }) => Promise<{} | null | undefined | CodedError<"NOT_FOUND">>
44
+ }
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "@toa.io/extensions.chronicles",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0-alpha.332",
4
+ "type": "module",
5
+ "description": "Toa Chronicles: a log of a context, kept in ClickHouse",
6
+ "author": "temich <tema.gurtovoy@gmail.com>",
7
+ "homepage": "https://github.com/toa-io/toa#readme",
8
+ "main": "transpiled/index.js",
9
+ "types": "transpiled/index.d.ts",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/toa-io/toa.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/toa-io/toa/issues"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "files": [
21
+ "transpiled",
22
+ "components",
23
+ "readme.md",
24
+ "!**/tsconfig.tsbuildinfo",
25
+ "!**/*.test.*",
26
+ "!**/.env*"
27
+ ],
28
+ "scripts": {
29
+ "transpile": "tsc"
30
+ },
31
+ "dependencies": {
32
+ "@toa.io/core": "1.0.0-alpha.332",
33
+ "@toa.io/definitions": "1.0.0-alpha.332",
34
+ "@toa.io/generic": "1.0.0-alpha.332",
35
+ "openspan": "1.0.0-alpha.330"
36
+ }
37
+ }