@hatk/hatk 0.0.1-alpha.6 → 0.0.1-alpha.61

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 (163) hide show
  1. package/dist/adapter.d.ts +19 -0
  2. package/dist/adapter.d.ts.map +1 -0
  3. package/dist/adapter.js +108 -0
  4. package/dist/backfill.d.ts +2 -2
  5. package/dist/backfill.d.ts.map +1 -1
  6. package/dist/backfill.js +83 -41
  7. package/dist/car.d.ts +42 -10
  8. package/dist/car.d.ts.map +1 -1
  9. package/dist/car.js +154 -14
  10. package/dist/cli.js +243 -1043
  11. package/dist/config.d.ts +31 -1
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +40 -9
  14. package/dist/database/adapter-factory.d.ts +6 -0
  15. package/dist/database/adapter-factory.d.ts.map +1 -0
  16. package/dist/database/adapter-factory.js +20 -0
  17. package/dist/database/adapters/duckdb-search.d.ts +12 -0
  18. package/dist/database/adapters/duckdb-search.d.ts.map +1 -0
  19. package/dist/database/adapters/duckdb-search.js +27 -0
  20. package/dist/database/adapters/duckdb.d.ts +25 -0
  21. package/dist/database/adapters/duckdb.d.ts.map +1 -0
  22. package/dist/database/adapters/duckdb.js +161 -0
  23. package/dist/database/adapters/sqlite-search.d.ts +23 -0
  24. package/dist/database/adapters/sqlite-search.d.ts.map +1 -0
  25. package/dist/database/adapters/sqlite-search.js +74 -0
  26. package/dist/database/adapters/sqlite.d.ts +18 -0
  27. package/dist/database/adapters/sqlite.d.ts.map +1 -0
  28. package/dist/database/adapters/sqlite.js +88 -0
  29. package/dist/{db.d.ts → database/db.d.ts} +57 -6
  30. package/dist/database/db.d.ts.map +1 -0
  31. package/dist/{db.js → database/db.js} +730 -549
  32. package/dist/database/dialect.d.ts +45 -0
  33. package/dist/database/dialect.d.ts.map +1 -0
  34. package/dist/database/dialect.js +72 -0
  35. package/dist/{fts.d.ts → database/fts.d.ts} +7 -0
  36. package/dist/database/fts.d.ts.map +1 -0
  37. package/dist/{fts.js → database/fts.js} +116 -32
  38. package/dist/database/index.d.ts +7 -0
  39. package/dist/database/index.d.ts.map +1 -0
  40. package/dist/database/index.js +6 -0
  41. package/dist/database/ports.d.ts +50 -0
  42. package/dist/database/ports.d.ts.map +1 -0
  43. package/dist/database/ports.js +1 -0
  44. package/dist/{schema.d.ts → database/schema.d.ts} +14 -3
  45. package/dist/database/schema.d.ts.map +1 -0
  46. package/dist/{schema.js → database/schema.js} +81 -41
  47. package/dist/dev-entry.d.ts +8 -0
  48. package/dist/dev-entry.d.ts.map +1 -0
  49. package/dist/dev-entry.js +113 -0
  50. package/dist/feeds.d.ts +12 -8
  51. package/dist/feeds.d.ts.map +1 -1
  52. package/dist/feeds.js +51 -6
  53. package/dist/hooks.d.ts +85 -0
  54. package/dist/hooks.d.ts.map +1 -0
  55. package/dist/hooks.js +161 -0
  56. package/dist/hydrate.d.ts +7 -6
  57. package/dist/hydrate.d.ts.map +1 -1
  58. package/dist/hydrate.js +4 -16
  59. package/dist/indexer.d.ts +23 -0
  60. package/dist/indexer.d.ts.map +1 -1
  61. package/dist/indexer.js +181 -34
  62. package/dist/labels.d.ts +36 -0
  63. package/dist/labels.d.ts.map +1 -1
  64. package/dist/labels.js +71 -6
  65. package/dist/lexicon-resolve.d.ts.map +1 -1
  66. package/dist/lexicon-resolve.js +27 -112
  67. package/dist/lexicons/com/atproto/label/defs.json +75 -0
  68. package/dist/lexicons/com/atproto/moderation/defs.json +30 -0
  69. package/dist/lexicons/com/atproto/repo/strongRef.json +24 -0
  70. package/dist/lexicons/dev/hatk/applyWrites.json +87 -0
  71. package/dist/lexicons/dev/hatk/createRecord.json +40 -0
  72. package/dist/lexicons/dev/hatk/createReport.json +48 -0
  73. package/dist/lexicons/dev/hatk/deleteRecord.json +25 -0
  74. package/dist/lexicons/dev/hatk/describeCollections.json +41 -0
  75. package/dist/lexicons/dev/hatk/describeFeeds.json +29 -0
  76. package/dist/lexicons/dev/hatk/describeLabels.json +45 -0
  77. package/dist/lexicons/dev/hatk/getFeed.json +30 -0
  78. package/dist/lexicons/dev/hatk/getPreferences.json +19 -0
  79. package/dist/lexicons/dev/hatk/getRecord.json +26 -0
  80. package/dist/lexicons/dev/hatk/getRecords.json +32 -0
  81. package/dist/lexicons/dev/hatk/putPreference.json +28 -0
  82. package/dist/lexicons/dev/hatk/putRecord.json +41 -0
  83. package/dist/lexicons/dev/hatk/searchRecords.json +32 -0
  84. package/dist/lexicons/dev/hatk/uploadBlob.json +23 -0
  85. package/dist/logger.d.ts +29 -0
  86. package/dist/logger.d.ts.map +1 -1
  87. package/dist/logger.js +29 -0
  88. package/dist/main.js +138 -67
  89. package/dist/mst.d.ts +18 -1
  90. package/dist/mst.d.ts.map +1 -1
  91. package/dist/mst.js +19 -8
  92. package/dist/oauth/db.d.ts +3 -1
  93. package/dist/oauth/db.d.ts.map +1 -1
  94. package/dist/oauth/db.js +48 -19
  95. package/dist/oauth/server.d.ts +24 -0
  96. package/dist/oauth/server.d.ts.map +1 -1
  97. package/dist/oauth/server.js +198 -22
  98. package/dist/oauth/session.d.ts +11 -0
  99. package/dist/oauth/session.d.ts.map +1 -0
  100. package/dist/oauth/session.js +65 -0
  101. package/dist/opengraph.d.ts +10 -0
  102. package/dist/opengraph.d.ts.map +1 -1
  103. package/dist/opengraph.js +80 -40
  104. package/dist/pds-proxy.d.ts +60 -0
  105. package/dist/pds-proxy.d.ts.map +1 -0
  106. package/dist/pds-proxy.js +277 -0
  107. package/dist/push.d.ts +34 -0
  108. package/dist/push.d.ts.map +1 -0
  109. package/dist/push.js +184 -0
  110. package/dist/renderer.d.ts +27 -0
  111. package/dist/renderer.d.ts.map +1 -0
  112. package/dist/renderer.js +46 -0
  113. package/dist/resolve-hatk.d.ts +6 -0
  114. package/dist/resolve-hatk.d.ts.map +1 -0
  115. package/dist/resolve-hatk.js +20 -0
  116. package/dist/response.d.ts +16 -0
  117. package/dist/response.d.ts.map +1 -0
  118. package/dist/response.js +69 -0
  119. package/dist/scanner.d.ts +21 -0
  120. package/dist/scanner.d.ts.map +1 -0
  121. package/dist/scanner.js +88 -0
  122. package/dist/seed.d.ts +19 -0
  123. package/dist/seed.d.ts.map +1 -1
  124. package/dist/seed.js +43 -4
  125. package/dist/server-init.d.ts +8 -0
  126. package/dist/server-init.d.ts.map +1 -0
  127. package/dist/server-init.js +62 -0
  128. package/dist/server.d.ts +26 -3
  129. package/dist/server.d.ts.map +1 -1
  130. package/dist/server.js +629 -635
  131. package/dist/setup.d.ts +28 -1
  132. package/dist/setup.d.ts.map +1 -1
  133. package/dist/setup.js +50 -3
  134. package/dist/templates/feed.tpl +14 -0
  135. package/dist/templates/hook.tpl +5 -0
  136. package/dist/templates/label.tpl +15 -0
  137. package/dist/templates/og.tpl +17 -0
  138. package/dist/templates/seed.tpl +11 -0
  139. package/dist/templates/setup.tpl +5 -0
  140. package/dist/templates/test-feed.tpl +19 -0
  141. package/dist/templates/test-xrpc.tpl +19 -0
  142. package/dist/templates/xrpc.tpl +41 -0
  143. package/dist/test.d.ts +1 -1
  144. package/dist/test.d.ts.map +1 -1
  145. package/dist/test.js +39 -32
  146. package/dist/views.js +1 -1
  147. package/dist/vite-plugin.d.ts +1 -1
  148. package/dist/vite-plugin.d.ts.map +1 -1
  149. package/dist/vite-plugin.js +254 -66
  150. package/dist/xrpc.d.ts +75 -11
  151. package/dist/xrpc.d.ts.map +1 -1
  152. package/dist/xrpc.js +189 -39
  153. package/package.json +14 -7
  154. package/public/admin.html +133 -54
  155. package/dist/db.d.ts.map +0 -1
  156. package/dist/fts.d.ts.map +0 -1
  157. package/dist/oauth/hooks.d.ts +0 -10
  158. package/dist/oauth/hooks.d.ts.map +0 -1
  159. package/dist/oauth/hooks.js +0 -40
  160. package/dist/schema.d.ts.map +0 -1
  161. package/dist/test-browser.d.ts +0 -14
  162. package/dist/test-browser.d.ts.map +0 -1
  163. package/dist/test-browser.js +0 -26
@@ -0,0 +1,25 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.deleteRecord",
4
+ "defs": {
5
+ "main": {
6
+ "type": "procedure",
7
+ "description": "Delete a record via the user's PDS.",
8
+ "input": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "required": ["collection", "rkey"],
13
+ "properties": {
14
+ "collection": { "type": "string" },
15
+ "rkey": { "type": "string" }
16
+ }
17
+ }
18
+ },
19
+ "output": {
20
+ "encoding": "application/json",
21
+ "schema": { "type": "object", "properties": {} }
22
+ }
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.describeCollections",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "List indexed collections and their schemas.",
8
+ "output": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "collections": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["collection"],
18
+ "properties": {
19
+ "collection": { "type": "string" },
20
+ "columns": {
21
+ "type": "array",
22
+ "items": {
23
+ "type": "object",
24
+ "required": ["name", "originalName", "type", "required"],
25
+ "properties": {
26
+ "name": { "type": "string" },
27
+ "originalName": { "type": "string" },
28
+ "type": { "type": "string" },
29
+ "required": { "type": "boolean" }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.describeFeeds",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "List available feeds.",
8
+ "output": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "feeds": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "required": ["name", "label"],
18
+ "properties": {
19
+ "name": { "type": "string" },
20
+ "label": { "type": "string" }
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.describeLabels",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "List available label definitions.",
8
+ "output": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "definitions": {
14
+ "type": "array",
15
+ "items": { "type": "ref", "ref": "#labelDefinition" }
16
+ }
17
+ }
18
+ }
19
+ }
20
+ },
21
+ "labelDefinition": {
22
+ "type": "object",
23
+ "required": ["identifier", "severity", "blurs", "defaultSetting"],
24
+ "properties": {
25
+ "identifier": { "type": "string" },
26
+ "severity": { "type": "string" },
27
+ "blurs": { "type": "string" },
28
+ "defaultSetting": { "type": "string" },
29
+ "locales": {
30
+ "type": "array",
31
+ "items": { "type": "ref", "ref": "#labelLocale" }
32
+ }
33
+ }
34
+ },
35
+ "labelLocale": {
36
+ "type": "object",
37
+ "required": ["lang", "name", "description"],
38
+ "properties": {
39
+ "lang": { "type": "string" },
40
+ "name": { "type": "string" },
41
+ "description": { "type": "string" }
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.getFeed",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "Retrieve a named feed of items.",
8
+ "parameters": {
9
+ "type": "params",
10
+ "required": ["feed"],
11
+ "properties": {
12
+ "feed": { "type": "string", "description": "Feed name" },
13
+ "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 30 },
14
+ "cursor": { "type": "string" }
15
+ }
16
+ },
17
+ "output": {
18
+ "encoding": "application/json",
19
+ "schema": {
20
+ "type": "object",
21
+ "required": ["items"],
22
+ "properties": {
23
+ "items": { "type": "array", "items": { "type": "unknown" } },
24
+ "cursor": { "type": "string" }
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.getPreferences",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "Get all preferences for the authenticated user.",
8
+ "output": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "preferences": { "type": "unknown" }
14
+ }
15
+ }
16
+ }
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.getRecord",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "Fetch a single record by AT URI.",
8
+ "parameters": {
9
+ "type": "params",
10
+ "required": ["uri"],
11
+ "properties": {
12
+ "uri": { "type": "string", "format": "at-uri" }
13
+ }
14
+ },
15
+ "output": {
16
+ "encoding": "application/json",
17
+ "schema": {
18
+ "type": "object",
19
+ "properties": {
20
+ "record": { "type": "unknown" }
21
+ }
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.getRecords",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "List records from a collection with optional filters.",
8
+ "parameters": {
9
+ "type": "params",
10
+ "required": ["collection"],
11
+ "properties": {
12
+ "collection": { "type": "string" },
13
+ "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 },
14
+ "cursor": { "type": "string" },
15
+ "sort": { "type": "string" },
16
+ "order": { "type": "string" }
17
+ }
18
+ },
19
+ "output": {
20
+ "encoding": "application/json",
21
+ "schema": {
22
+ "type": "object",
23
+ "required": ["items"],
24
+ "properties": {
25
+ "items": { "type": "array", "items": { "type": "unknown" } },
26
+ "cursor": { "type": "string" }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.putPreference",
4
+ "defs": {
5
+ "main": {
6
+ "type": "procedure",
7
+ "description": "Set a single preference by key.",
8
+ "input": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "required": ["key", "value"],
13
+ "properties": {
14
+ "key": { "type": "string" },
15
+ "value": { "type": "unknown" }
16
+ }
17
+ }
18
+ },
19
+ "output": {
20
+ "encoding": "application/json",
21
+ "schema": {
22
+ "type": "object",
23
+ "properties": {}
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.putRecord",
4
+ "defs": {
5
+ "main": {
6
+ "type": "procedure",
7
+ "description": "Create or update a record via the user's PDS.",
8
+ "input": {
9
+ "encoding": "application/json",
10
+ "schema": {
11
+ "type": "object",
12
+ "required": ["collection", "rkey", "record"],
13
+ "properties": {
14
+ "collection": { "type": "string" },
15
+ "rkey": { "type": "string" },
16
+ "record": { "type": "unknown" },
17
+ "repo": { "type": "string", "format": "did" }
18
+ }
19
+ }
20
+ },
21
+ "output": {
22
+ "encoding": "application/json",
23
+ "schema": {
24
+ "type": "object",
25
+ "properties": {
26
+ "uri": { "type": "string", "format": "at-uri" },
27
+ "cid": { "type": "string", "format": "cid" },
28
+ "commit": {
29
+ "type": "object",
30
+ "properties": {
31
+ "cid": { "type": "string", "format": "cid" },
32
+ "rev": { "type": "string" }
33
+ }
34
+ },
35
+ "validationStatus": { "type": "string" }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.searchRecords",
4
+ "defs": {
5
+ "main": {
6
+ "type": "query",
7
+ "description": "Full-text search across a collection.",
8
+ "parameters": {
9
+ "type": "params",
10
+ "required": ["collection", "q"],
11
+ "properties": {
12
+ "collection": { "type": "string" },
13
+ "q": { "type": "string", "description": "Search query" },
14
+ "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 },
15
+ "cursor": { "type": "string" },
16
+ "fuzzy": { "type": "boolean", "default": true }
17
+ }
18
+ },
19
+ "output": {
20
+ "encoding": "application/json",
21
+ "schema": {
22
+ "type": "object",
23
+ "required": ["items"],
24
+ "properties": {
25
+ "items": { "type": "array", "items": { "type": "unknown" } },
26
+ "cursor": { "type": "string" }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "lexicon": 1,
3
+ "id": "dev.hatk.uploadBlob",
4
+ "defs": {
5
+ "main": {
6
+ "type": "procedure",
7
+ "description": "Upload a blob via the user's PDS.",
8
+ "input": {
9
+ "encoding": "*/*"
10
+ },
11
+ "output": {
12
+ "encoding": "application/json",
13
+ "schema": {
14
+ "type": "object",
15
+ "required": ["blob"],
16
+ "properties": {
17
+ "blob": { "type": "blob" }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
23
+ }
package/dist/logger.d.ts CHANGED
@@ -1,4 +1,33 @@
1
+ /**
2
+ * Unstructured debug log — use sparingly for human-readable dev output.
3
+ * Prefer {@link emit} for anything that should be queryable in production.
4
+ * Disabled when `DEBUG=0`.
5
+ */
1
6
  export declare function log(...args: unknown[]): void;
7
+ /**
8
+ * Emit a structured wide event as a single JSON line to stdout.
9
+ *
10
+ * Each call produces one canonical log line with a timestamp, module, operation,
11
+ * and arbitrary key-value fields — designed for columnar search and aggregation,
12
+ * not string grep. Pack as much context as possible into `fields` (request IDs,
13
+ * durations, status codes, user DIDs, counts) so a single event tells the full
14
+ * story. See https://loggingsucks.com for the philosophy behind this approach.
15
+ *
16
+ * Disabled when `DEBUG=0`.
17
+ *
18
+ * @param module - Subsystem emitting the event (e.g. "server", "indexer", "backfill")
19
+ * @param op - Operation name (e.g. "request", "commit", "memory")
20
+ * @param fields - High-cardinality key-value context — include everything relevant
21
+ */
2
22
  export declare function emit(module: string, op: string, fields: Record<string, unknown>): void;
23
+ /**
24
+ * Start a millisecond timer. Call the returned function to get elapsed ms.
25
+ * Use with {@link emit} to add `duration_ms` to wide events.
26
+ *
27
+ * @example
28
+ * const elapsed = timer()
29
+ * await doWork()
30
+ * emit('server', 'request', { path, status_code, duration_ms: elapsed() })
31
+ */
3
32
  export declare function timer(): () => number;
4
33
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAG5C;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWtF;AAED,wBAAgB,KAAK,IAAI,MAAM,MAAM,CAGpC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAG5C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWtF;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,IAAI,MAAM,MAAM,CAGpC"}
package/dist/logger.js CHANGED
@@ -1,8 +1,28 @@
1
+ /**
2
+ * Unstructured debug log — use sparingly for human-readable dev output.
3
+ * Prefer {@link emit} for anything that should be queryable in production.
4
+ * Disabled when `DEBUG=0`.
5
+ */
1
6
  export function log(...args) {
2
7
  if (process.env.DEBUG === '0')
3
8
  return;
4
9
  console.log(...args);
5
10
  }
11
+ /**
12
+ * Emit a structured wide event as a single JSON line to stdout.
13
+ *
14
+ * Each call produces one canonical log line with a timestamp, module, operation,
15
+ * and arbitrary key-value fields — designed for columnar search and aggregation,
16
+ * not string grep. Pack as much context as possible into `fields` (request IDs,
17
+ * durations, status codes, user DIDs, counts) so a single event tells the full
18
+ * story. See https://loggingsucks.com for the philosophy behind this approach.
19
+ *
20
+ * Disabled when `DEBUG=0`.
21
+ *
22
+ * @param module - Subsystem emitting the event (e.g. "server", "indexer", "backfill")
23
+ * @param op - Operation name (e.g. "request", "commit", "memory")
24
+ * @param fields - High-cardinality key-value context — include everything relevant
25
+ */
6
26
  export function emit(module, op, fields) {
7
27
  if (process.env.DEBUG === '0')
8
28
  return;
@@ -17,6 +37,15 @@ export function emit(module, op, fields) {
17
37
  }
18
38
  process.stdout.write(JSON.stringify(entry) + '\n');
19
39
  }
40
+ /**
41
+ * Start a millisecond timer. Call the returned function to get elapsed ms.
42
+ * Use with {@link emit} to add `duration_ms` to wide events.
43
+ *
44
+ * @example
45
+ * const elapsed = timer()
46
+ * await doWork()
47
+ * emit('server', 'request', { path, status_code, duration_ms: elapsed() })
48
+ */
20
49
  export function timer() {
21
50
  const start = performance.now();
22
51
  return () => Math.round(performance.now() - start);