@remit/search-index-worker 0.0.1 → 0.0.2

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/package.json CHANGED
@@ -1,50 +1,54 @@
1
1
  {
2
- "name": "@remit/search-index-worker",
3
- "version": "0.0.1",
4
- "type": "module",
5
- "main": "dist/index.js",
6
- "exports": {
7
- ".": {
8
- "types": "./src/index.ts",
9
- "default": "./src/index.ts"
10
- }
11
- },
12
- "scripts": {
13
- "test:typecheck": "tsgo --noEmit",
14
- "test:run": "node --env-file=../../localhost-test-unit.env --import tsx --test 'src/**/*.test.ts'",
15
- "test:integ": "RUN_INTEG_TESTS=1 node --env-file=../../localhost-test-unit.env --import tsx --test 'src/**/*.integ.test.ts'",
16
- "test": "npm run test:typecheck && npm run test:run"
17
- },
18
- "dependencies": {
19
- "@remit/outbox-relay": "*",
20
- "p-map": "*",
21
- "pg": "^8.0.0"
22
- },
23
- "devDependencies": {
24
- "@aws-sdk/client-dynamodb": "*",
25
- "@aws-sdk/client-sqs": "*",
26
- "@aws-sdk/core": "*",
27
- "@aws-sdk/lib-dynamodb": "*",
28
- "@remit/data-ports": "*",
29
- "@remit/drizzle-service": "*",
30
- "better-sqlite3": "^12.11.1",
31
- "@remit/logger-lambda": "*",
32
- "@remit/search-service": "*",
33
- "@remit/sqs-client": "*",
34
- "@remit/storage-service": "*",
35
- "@types/aws-lambda": "*",
36
- "@types/pg": "^8.0.0",
37
- "expect-env": "*",
38
- "tsx": "*",
39
- "zod": "*"
40
- },
41
- "license": "MIT",
42
- "publishConfig": {
43
- "access": "public"
44
- },
45
- "repository": {
46
- "type": "git",
47
- "url": "git+https://github.com/remit-mail/remit.git",
48
- "directory": "packages/search-index-worker"
49
- }
2
+ "name": "@remit/search-index-worker",
3
+ "version": "0.0.2",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./src/index.ts",
9
+ "default": "./src/index.ts"
10
+ },
11
+ "./data-ports": {
12
+ "types": "./src/data-ports.ts",
13
+ "default": "./src/data-ports.ts"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "test:typecheck": "tsgo --noEmit",
18
+ "test:run": "node --env-file=../../localhost-test-unit.env --import tsx --test 'src/**/*.test.ts'",
19
+ "test:integ": "RUN_INTEG_TESTS=1 node --env-file=../../localhost-test-unit.env --import tsx --test 'src/**/*.integ.test.ts'",
20
+ "test": "npm run test:typecheck && npm run test:run"
21
+ },
22
+ "dependencies": {
23
+ "@remit/outbox-relay": "*",
24
+ "p-map": "*",
25
+ "pg": "^8.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@aws-sdk/client-dynamodb": "*",
29
+ "@aws-sdk/client-sqs": "*",
30
+ "@aws-sdk/core": "*",
31
+ "@aws-sdk/lib-dynamodb": "*",
32
+ "@remit/data-ports": "*",
33
+ "@remit/drizzle-service": "*",
34
+ "better-sqlite3": "^12.11.1",
35
+ "@remit/logger-lambda": "*",
36
+ "@remit/search-service": "*",
37
+ "@remit/sqs-client": "*",
38
+ "@remit/storage-service": "*",
39
+ "@types/aws-lambda": "*",
40
+ "@types/pg": "^8.0.0",
41
+ "expect-env": "*",
42
+ "tsx": "*",
43
+ "zod": "*"
44
+ },
45
+ "license": "MIT",
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/remit-mail/remit.git",
52
+ "directory": "packages/search-index-worker"
53
+ }
50
54
  }
@@ -1,14 +1,10 @@
1
1
  import assert from "node:assert/strict";
2
- import { existsSync } from "node:fs";
3
2
  import { afterEach, test } from "node:test";
4
- import { fileURLToPath } from "node:url";
5
- import { buildDataPortsFromEnv } from "./data-ports.js";
6
-
7
- // The DynamoDB composition module is stripped from the open-core tree; the
8
- // DynamoDB-path cases skip there and run where the module ships.
9
- const hasDynamoComposition = existsSync(
10
- fileURLToPath(new URL("./compose-dynamodb.ts", import.meta.url)),
11
- );
3
+ import {
4
+ buildDataPortsFromEnv,
5
+ type SearchIndexDataPorts,
6
+ setSearchIndexDataPorts,
7
+ } from "./data-ports.js";
12
8
 
13
9
  const withEnv = async (
14
10
  overrides: Record<string, string | undefined>,
@@ -34,38 +30,26 @@ afterEach(() => {
34
30
  delete process.env.DATA_BACKEND;
35
31
  });
36
32
 
37
- test(
38
- "without DATA_BACKEND builds DynamoDB (electrodb) ports and no resolveAccountId hook",
39
- { skip: !hasDynamoComposition },
40
- async () => {
41
- await withEnv(
42
- { DATA_BACKEND: undefined, DYNAMODB_TABLE_NAME: "remit-test" },
43
- async () => {
44
- const ports = await buildDataPortsFromEnv();
45
- assert.ok(ports.account, "account port must be defined");
46
- assert.ok(ports.threadMessage, "threadMessage port must be defined");
47
- assert.equal(
48
- ports.resolveAccountId,
49
- undefined,
50
- "DynamoDB messages already carry a real accountId — no resolution hook",
51
- );
52
- },
33
+ test("without DATA_BACKEND and no registered ports, throws (DynamoDB path is injected)", async () => {
34
+ await withEnv({ DATA_BACKEND: undefined }, async () => {
35
+ await assert.rejects(
36
+ () => buildDataPortsFromEnv(),
37
+ /no DynamoDB search-index data ports registered/,
53
38
  );
54
- },
55
- );
39
+ });
40
+ });
56
41
 
57
- test(
58
- "without DATA_BACKEND and no DYNAMODB_TABLE_NAME throws",
59
- { skip: !hasDynamoComposition },
60
- async () => {
61
- await withEnv(
62
- { DATA_BACKEND: undefined, DYNAMODB_TABLE_NAME: undefined },
63
- async () => {
64
- await assert.rejects(() => buildDataPortsFromEnv());
65
- },
66
- );
67
- },
68
- );
42
+ test("without DATA_BACKEND returns the injected DynamoDB ports", async () => {
43
+ const injected = {
44
+ account: {},
45
+ threadMessage: {},
46
+ } as unknown as SearchIndexDataPorts;
47
+ setSearchIndexDataPorts(injected);
48
+ await withEnv({ DATA_BACKEND: undefined }, async () => {
49
+ const ports = await buildDataPortsFromEnv();
50
+ assert.equal(ports, injected);
51
+ });
52
+ });
69
53
 
70
54
  test("DATA_BACKEND=postgres builds Drizzle ports with a resolveAccountId hook, without connecting", async () => {
71
55
  await withEnv(
package/src/data-ports.ts CHANGED
@@ -119,24 +119,29 @@ const buildSqliteDataPorts = async (): Promise<SearchIndexDataPorts> => {
119
119
  * - otherwise → ElectroDB services over `DYNAMODB_TABLE_NAME` (unchanged from
120
120
  * the pre-convergence worker — this is the production path).
121
121
  *
122
- * Each branch loads its composition module through a dynamic `import()`, so the
123
- * DynamoDB path the sole importer of the closed `@remit/remit-electrodb-
124
- * service` (`./compose-dynamodb.js`) — is never loaded on the relational
125
- * (open-core) tree, where that module is not shipped. esbuild still bundles it
126
- * into the Lambda because the specifier is a relative import, not an `external`.
122
+ * The DynamoDB ports are injected by the composition root, which lives outside
123
+ * this shared, open-core module and is never imported here.
127
124
  */
125
+ let injectedDataPorts: SearchIndexDataPorts | null = null;
126
+
127
+ /**
128
+ * Register the DynamoDB-backed search-index data ports from the composition
129
+ * root. The relational backends compose in-package above and never touch this
130
+ * seam.
131
+ */
132
+ export const setSearchIndexDataPorts = (ports: SearchIndexDataPorts): void => {
133
+ injectedDataPorts = ports;
134
+ };
135
+
128
136
  export const buildDataPortsFromEnv =
129
137
  async (): Promise<SearchIndexDataPorts> => {
130
138
  if (process.env.DATA_BACKEND === "postgres")
131
139
  return buildPostgresDataPorts();
132
140
  if (process.env.DATA_BACKEND === "sqlite") return buildSqliteDataPorts();
133
- // `as string` stops tsgo resolving the module in the open-core tree, which
134
- // strips it; the named contract keeps the call site typed rather than `any`.
135
- type ComposeDynamoDBModule = {
136
- buildDynamoDBDataPorts: () => SearchIndexDataPorts;
137
- };
138
- const { buildDynamoDBDataPorts } = (await import(
139
- "./compose-dynamodb.js" as string
140
- )) as ComposeDynamoDBModule;
141
- return buildDynamoDBDataPorts();
141
+ if (!injectedDataPorts) {
142
+ throw new Error(
143
+ "no DynamoDB search-index data ports registered — register them with setSearchIndexDataPorts() from your composition root",
144
+ );
145
+ }
146
+ return injectedDataPorts;
142
147
  };
package/src/services.ts CHANGED
@@ -1,4 +1,7 @@
1
- import { createSearchService, type SearchService } from "@remit/search-service";
1
+ import {
2
+ createSearchService,
3
+ type SearchService,
4
+ } from "@remit/search-service";
2
5
  import {
3
6
  buildEmbeddingServiceFromEnv,
4
7
  buildVectorStoreFromEnv,