@venizia/ignis-worker 0.2.0-9 → 0.2.1-0
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/README.md +133 -0
- package/dist/cjs/applications/common/index.d.ts +2 -0
- package/dist/cjs/applications/common/index.d.ts.map +1 -0
- package/dist/cjs/applications/common/index.js +18 -0
- package/dist/cjs/applications/common/index.js.map +1 -0
- package/dist/cjs/applications/common/types.d.ts +10 -0
- package/dist/cjs/applications/common/types.d.ts.map +1 -0
- package/dist/cjs/applications/common/types.js.map +1 -0
- package/dist/cjs/applications/index.d.ts +1 -0
- package/dist/cjs/applications/index.d.ts.map +1 -1
- package/dist/cjs/applications/index.js +1 -0
- package/dist/cjs/applications/index.js.map +1 -1
- package/dist/cjs/applications/worker.d.ts +18 -6
- package/dist/cjs/applications/worker.d.ts.map +1 -1
- package/dist/cjs/applications/worker.js +21 -6
- package/dist/cjs/applications/worker.js.map +1 -1
- package/dist/cjs/envelope/common/index.d.ts +2 -0
- package/dist/cjs/envelope/common/index.d.ts.map +1 -0
- package/dist/cjs/envelope/common/index.js +18 -0
- package/dist/cjs/envelope/common/index.js.map +1 -0
- package/dist/cjs/envelope/common/types.d.ts.map +1 -0
- package/dist/cjs/envelope/common/types.js +3 -0
- package/dist/{esm/envelope → cjs/envelope/common}/types.js.map +1 -1
- package/dist/cjs/envelope/encode.d.ts +1 -1
- package/dist/cjs/envelope/encode.d.ts.map +1 -1
- package/dist/cjs/envelope/index.d.ts +1 -1
- package/dist/cjs/envelope/index.d.ts.map +1 -1
- package/dist/cjs/envelope/index.js +1 -1
- package/dist/cjs/envelope/index.js.map +1 -1
- package/dist/cjs/transport/fetch-bridge.d.ts +8 -2
- package/dist/cjs/transport/fetch-bridge.d.ts.map +1 -1
- package/dist/cjs/transport/fetch-bridge.js +12 -3
- package/dist/cjs/transport/fetch-bridge.js.map +1 -1
- package/dist/cjs/transport/shared/common/constants.d.ts +14 -0
- package/dist/cjs/transport/shared/common/constants.d.ts.map +1 -0
- package/dist/cjs/transport/shared/common/constants.js +19 -0
- package/dist/cjs/transport/shared/common/constants.js.map +1 -0
- package/dist/cjs/transport/shared/common/index.d.ts +3 -0
- package/dist/cjs/transport/shared/common/index.d.ts.map +1 -0
- package/dist/cjs/transport/shared/common/index.js +19 -0
- package/dist/cjs/transport/shared/common/index.js.map +1 -0
- package/dist/cjs/transport/shared/common/types.d.ts +35 -0
- package/dist/cjs/transport/shared/common/types.d.ts.map +1 -0
- package/dist/cjs/transport/shared/common/types.js +3 -0
- package/dist/cjs/transport/shared/common/types.js.map +1 -0
- package/dist/cjs/transport/shared/index.d.ts +4 -0
- package/dist/cjs/transport/shared/index.d.ts.map +1 -0
- package/dist/cjs/transport/shared/index.js +11 -0
- package/dist/cjs/transport/shared/index.js.map +1 -0
- package/dist/cjs/transport/{shared.d.ts → shared/transport.d.ts} +3 -18
- package/dist/cjs/transport/shared/transport.d.ts.map +1 -0
- package/dist/cjs/transport/{shared.js → shared/transport.js} +22 -34
- package/dist/cjs/transport/shared/transport.js.map +1 -0
- package/dist/cjs/transport/worker.d.ts.map +1 -1
- package/dist/cjs/transport/worker.js +2 -1
- package/dist/cjs/transport/worker.js.map +1 -1
- package/dist/esm/applications/common/index.d.ts +2 -0
- package/dist/esm/applications/common/index.d.ts.map +1 -0
- package/dist/esm/applications/common/index.js +2 -0
- package/dist/esm/applications/common/index.js.map +1 -0
- package/dist/esm/applications/common/types.d.ts +10 -0
- package/dist/esm/applications/common/types.d.ts.map +1 -0
- package/dist/esm/applications/common/types.js.map +1 -0
- package/dist/esm/applications/index.d.ts +1 -0
- package/dist/esm/applications/index.d.ts.map +1 -1
- package/dist/esm/applications/index.js +1 -0
- package/dist/esm/applications/index.js.map +1 -1
- package/dist/esm/applications/worker.d.ts +18 -6
- package/dist/esm/applications/worker.d.ts.map +1 -1
- package/dist/esm/applications/worker.js +23 -8
- package/dist/esm/applications/worker.js.map +1 -1
- package/dist/esm/envelope/common/index.d.ts +2 -0
- package/dist/esm/envelope/common/index.d.ts.map +1 -0
- package/dist/esm/envelope/common/index.js +2 -0
- package/dist/esm/envelope/common/index.js.map +1 -0
- package/dist/esm/envelope/common/types.d.ts.map +1 -0
- package/dist/esm/envelope/common/types.js +2 -0
- package/dist/{cjs/envelope → esm/envelope/common}/types.js.map +1 -1
- package/dist/esm/envelope/encode.d.ts +1 -1
- package/dist/esm/envelope/encode.d.ts.map +1 -1
- package/dist/esm/envelope/index.d.ts +1 -1
- package/dist/esm/envelope/index.d.ts.map +1 -1
- package/dist/esm/envelope/index.js +1 -1
- package/dist/esm/envelope/index.js.map +1 -1
- package/dist/esm/package.json +6 -0
- package/dist/esm/transport/fetch-bridge.d.ts +8 -2
- package/dist/esm/transport/fetch-bridge.d.ts.map +1 -1
- package/dist/esm/transport/fetch-bridge.js +12 -3
- package/dist/esm/transport/fetch-bridge.js.map +1 -1
- package/dist/esm/transport/index.d.ts +1 -1
- package/dist/esm/transport/index.js +1 -1
- package/dist/esm/transport/shared/common/constants.d.ts +14 -0
- package/dist/esm/transport/shared/common/constants.d.ts.map +1 -0
- package/dist/esm/transport/shared/common/constants.js +14 -0
- package/dist/esm/transport/shared/common/constants.js.map +1 -0
- package/dist/esm/transport/shared/common/index.d.ts +3 -0
- package/dist/esm/transport/shared/common/index.d.ts.map +1 -0
- package/dist/esm/transport/shared/common/index.js +3 -0
- package/dist/esm/transport/shared/common/index.js.map +1 -0
- package/dist/esm/transport/shared/common/types.d.ts +35 -0
- package/dist/esm/transport/shared/common/types.d.ts.map +1 -0
- package/dist/esm/transport/shared/common/types.js +2 -0
- package/dist/esm/transport/shared/common/types.js.map +1 -0
- package/dist/esm/transport/shared/index.d.ts +4 -0
- package/dist/esm/transport/shared/index.d.ts.map +1 -0
- package/dist/esm/transport/shared/index.js +6 -0
- package/dist/esm/transport/shared/index.js.map +1 -0
- package/dist/esm/transport/{shared.d.ts → shared/transport.d.ts} +3 -18
- package/dist/esm/transport/shared/transport.d.ts.map +1 -0
- package/dist/esm/transport/{shared.js → shared/transport.js} +6 -17
- package/dist/esm/transport/shared/transport.js.map +1 -0
- package/dist/esm/transport/worker.d.ts.map +1 -1
- package/dist/esm/transport/worker.js +2 -1
- package/dist/esm/transport/worker.js.map +1 -1
- package/package.json +10 -10
- package/dist/cjs/envelope/types.d.ts.map +0 -1
- package/dist/cjs/transport/shared.d.ts.map +0 -1
- package/dist/cjs/transport/shared.js.map +0 -1
- package/dist/esm/envelope/types.d.ts.map +0 -1
- package/dist/esm/transport/shared.d.ts.map +0 -1
- package/dist/esm/transport/shared.js.map +0 -1
- /package/dist/cjs/{envelope → applications/common}/types.js +0 -0
- /package/dist/cjs/envelope/{types.d.ts → common/types.d.ts} +0 -0
- /package/dist/esm/{envelope → applications/common}/types.js +0 -0
- /package/dist/esm/envelope/{types.d.ts → common/types.d.ts} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# @venizia/ignis-worker
|
|
2
|
+
|
|
3
|
+
Runs an IGNIS application inside a browser Web Worker. The page calls it like an HTTP API, and
|
|
4
|
+
nothing crosses a network: requests travel over `postMessage`.
|
|
5
|
+
|
|
6
|
+
Use it to build a Backend for Frontend (BFF) - a backend that serves one user interface and lives in
|
|
7
|
+
that interface's own tab. Your controllers, services and repositories are the same classes a server
|
|
8
|
+
application uses; only the host changes.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun add @venizia/ignis-worker @venizia/ignis-kernel hono @hono/zod-openapi
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Add `@venizia/ignis-connectors` and a driver when the BFF needs a database, for example
|
|
17
|
+
`@electric-sql/pglite` for Postgres stored in the browser.
|
|
18
|
+
|
|
19
|
+
## Example
|
|
20
|
+
|
|
21
|
+
Inside the Worker, extend `WorkerApplication` and call `listen()` instead of `start()`:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// worker.ts
|
|
25
|
+
import { z } from '@hono/zod-openapi';
|
|
26
|
+
import { BaseRestController, controller, get, jsonResponse } from '@venizia/ignis-kernel';
|
|
27
|
+
import { WorkerApplication } from '@venizia/ignis-worker';
|
|
28
|
+
import type { Context } from 'hono';
|
|
29
|
+
|
|
30
|
+
@controller({ path: '/notes' })
|
|
31
|
+
class NoteController extends BaseRestController {
|
|
32
|
+
constructor() {
|
|
33
|
+
super({ scope: NoteController.name });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override binding() {}
|
|
37
|
+
|
|
38
|
+
@get({
|
|
39
|
+
configs: {
|
|
40
|
+
path: '/',
|
|
41
|
+
responses: jsonResponse({ schema: z.array(z.object({ title: z.string() })) }),
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
list(context: Context) {
|
|
45
|
+
return context.json([{ title: 'Answered inside the Worker' }]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class BffApplication extends WorkerApplication {
|
|
50
|
+
getAppInfo() {
|
|
51
|
+
return { name: 'bff', version: '1.0.0', description: 'A BFF in a Worker' };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
staticConfigure() {}
|
|
55
|
+
setupMiddlewares() {}
|
|
56
|
+
postConfigure() {}
|
|
57
|
+
|
|
58
|
+
preConfigure() {
|
|
59
|
+
this.controller(NoteController);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const application = new BffApplication({
|
|
64
|
+
scope: BffApplication.name,
|
|
65
|
+
config: { path: { base: '/api', isStrict: false }, error: { environment: 'development' } },
|
|
66
|
+
});
|
|
67
|
+
application.init();
|
|
68
|
+
await application.listen();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
On the page, create a transport and send it a `Request`:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// page.ts
|
|
75
|
+
import { SharedBffTransport } from '@venizia/ignis-worker';
|
|
76
|
+
|
|
77
|
+
const bff = new SharedBffTransport({
|
|
78
|
+
createWorker: () => new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const response = await bff.fetch({ request: new Request('http://ignis.internal/api/notes') });
|
|
82
|
+
console.log(response.status, await response.json()); // 200 [ { title: 'Answered inside the Worker' } ]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
A Worker has no `process.env`, so set `config.error.environment` yourself. `listen()` queues any
|
|
86
|
+
request that arrives while the application is still booting.
|
|
87
|
+
|
|
88
|
+
## Make an existing client use it
|
|
89
|
+
|
|
90
|
+
Most HTTP clients do not accept a custom fetcher. `installBffFetch` answers the page's global `fetch`
|
|
91
|
+
for every URL under `basePath` and leaves every other call on the network:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { installBffFetch } from '@venizia/ignis-worker';
|
|
95
|
+
|
|
96
|
+
installBffFetch({ transport: bff, basePath: '/api' });
|
|
97
|
+
|
|
98
|
+
await fetch('/api/notes'); // answered by the Worker
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Install it before the code that calls `fetch` starts. It returns a function that uninstalls it.
|
|
102
|
+
|
|
103
|
+
## What it exports
|
|
104
|
+
|
|
105
|
+
| Export | What it does |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `WorkerApplication` | A `RestApplication` host with `listen({ scope? })` and `stop()` in place of a socket |
|
|
108
|
+
| `SharedBffTransport` | One Worker per origin. It elects one tab with the Web Locks API and forwards the other tabs' requests over a `BroadcastChannel`. Use it by default |
|
|
109
|
+
| `WorkerBffTransport` | One Worker per transport, for a BFF that holds no origin-exclusive resource |
|
|
110
|
+
| `InProcessBffTransport` | No Worker - the same envelope round trip in one thread, for tests |
|
|
111
|
+
| `installBffFetch` | Routes the global `fetch` into a transport |
|
|
112
|
+
| `BffEnvelope`, `BFF_SYNTHETIC_ORIGIN` | The request, response and error envelopes that cross `postMessage` |
|
|
113
|
+
|
|
114
|
+
`SharedBffTransport` exists because a database like PGlite in OPFS holds an exclusive per-origin
|
|
115
|
+
handle. A second tab starting its own Worker could not open it.
|
|
116
|
+
|
|
117
|
+
The package has one entry point, `@venizia/ignis-worker`. `hono` and `@hono/zod-openapi` are its only
|
|
118
|
+
peers, and both are required.
|
|
119
|
+
|
|
120
|
+
## Where it sits
|
|
121
|
+
|
|
122
|
+
Depends on `@venizia/ignis-kernel`, `@venizia/ignis-helpers` and `@venizia/ignis-inversion`. It is the
|
|
123
|
+
browser sibling of `@venizia/ignis`; neither depends on the other, and it does not depend on
|
|
124
|
+
`@venizia/ignis-connectors`.
|
|
125
|
+
|
|
126
|
+
## Links
|
|
127
|
+
|
|
128
|
+
- [Example: browser-bff](https://github.com/VENIZIA-AI/ignis/tree/main/examples/browser-bff) - a controller answering from PGlite in OPFS, with no server
|
|
129
|
+
- [Changelog: the browser-pure kernel](https://ignis.venizia.ai/changelogs/2026-08-13-browser-pure-kernel)
|
|
130
|
+
- [Changelog: a BFF shared across tabs](https://ignis.venizia.ai/changelogs/2026-08-19-browser-bff-multi-tab)
|
|
131
|
+
- [All changelogs](https://ignis.venizia.ai/changelogs/)
|
|
132
|
+
|
|
133
|
+
MIT licensed - see [LICENSE.md](https://github.com/VENIZIA-AI/ignis/blob/main/LICENSE.md).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/applications/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/applications/common/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IApplicationConfigs } from '@venizia/ignis-kernel';
|
|
2
|
+
/**
|
|
3
|
+
* What a Web Worker host configures on top of the kernel's shape. `host`/`port` stay off this
|
|
4
|
+
* interface on purpose - `@venizia/ignis`'s `IServerApplicationConfigs` is the one with a socket.
|
|
5
|
+
*/
|
|
6
|
+
export interface IWorkerApplicationConfigs extends IApplicationConfigs {
|
|
7
|
+
/** Bound as `CoreBindings.APPLICATION_PROJECT_ROOT` when `getProjectRoot()` resolves it, and shared with `ModuleUtility`; default is the host's own working directory when one exists, else `''`. */
|
|
8
|
+
projectRoot?: string;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/applications/common/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,qMAAqM;IACrM,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/applications/common/types.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/applications/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/applications/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
|
|
@@ -14,5 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./common"), exports);
|
|
17
18
|
__exportStar(require("./worker"), exports);
|
|
18
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/applications/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/applications/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,2CAAyB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RestApplication } from '@venizia/ignis-kernel';
|
|
2
2
|
import type { Env, Schema } from 'hono';
|
|
3
|
+
import type { IWorkerApplicationConfigs } from './common';
|
|
3
4
|
/**
|
|
4
5
|
* Structural shape of the two globals `listen()` can attach to. Never `DedicatedWorkerGlobalScope`:
|
|
5
6
|
* naming it emits it into the published `.d.ts` and forces every consumer to compile with
|
|
@@ -19,12 +20,23 @@ export interface IWorkerMessageScope {
|
|
|
19
20
|
* reason the DI helpers and `RestComponent` sit in the kernel.
|
|
20
21
|
*/
|
|
21
22
|
export declare abstract class WorkerApplication<AppEnv extends Env = Env, AppSchema extends Schema = {}, BasePath extends string = '/'> extends RestApplication<AppEnv, AppSchema, BasePath> {
|
|
23
|
+
/** Widened by this layer, the only one with an optional `projectRoot` to read. Assigned by the base constructor - `declare` so no field initializer runs here and overwrites it with `undefined`. */
|
|
24
|
+
protected configs: IWorkerApplicationConfigs;
|
|
22
25
|
/** Resolves once the router tree is mounted - what an envelope arriving during boot waits on. */
|
|
23
26
|
private servingPromise?;
|
|
24
27
|
/** The whole `listen()` call, kept so a second one is a no-op instead of a second listener. */
|
|
25
28
|
private listenPromise?;
|
|
26
29
|
private detachFromScope?;
|
|
27
30
|
private isStopped;
|
|
31
|
+
/**
|
|
32
|
+
* `configs.projectRoot` wins, else the host's own working directory - read as
|
|
33
|
+
* `globalThis.process?.cwd?.()`, never a bare `process.cwd()`, because a real browser Worker has no
|
|
34
|
+
* such global and this class ships there. Bound AND shared with `ModuleUtility` (through the
|
|
35
|
+
* purity-safe `ProjectRootRegistry`), the same seam `ServerApplication` gives a socket host. No
|
|
36
|
+
* `node_modules` check here, unlike that host: a browser has no filesystem to check, and `node:fs`
|
|
37
|
+
* would bundle a Node builtin straight into a Worker.
|
|
38
|
+
*/
|
|
39
|
+
getProjectRoot(): string;
|
|
28
40
|
/**
|
|
29
41
|
* Every failure here is posted back as an `IBffErrorEnvelope`, the failed `postMessage` included:
|
|
30
42
|
* an exception nobody posts leaves the UI waiting out the transport timeout.
|
|
@@ -53,14 +65,14 @@ export declare abstract class WorkerApplication<AppEnv extends Env = Env, AppSch
|
|
|
53
65
|
scope?: MessagePort | IWorkerMessageScope;
|
|
54
66
|
}): Promise<void>;
|
|
55
67
|
/**
|
|
56
|
-
* The counterpart to `listen()`, and to `ServerApplication.stop()`:
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
68
|
+
* The counterpart to `listen()`, and to `ServerApplication.stop()`: runs the post-stop hooks, then
|
|
69
|
+
* closes every datasource the boot configured. Without it the OPFS exclusive lock a PGlite holds
|
|
70
|
+
* is never released - the next Worker then fails with `NoModificationAllowedError` until a full
|
|
71
|
+
* page reload. The Vite recipe is `import.meta.hot?.dispose(() => application.stop())`.
|
|
60
72
|
*
|
|
61
73
|
* Detaches BEFORE draining, unlike the server: here the listener IS the socket, and a request
|
|
62
|
-
* admitted while
|
|
63
|
-
*
|
|
74
|
+
* admitted while a datasource is closing has nothing left to run against. A stopped application
|
|
75
|
+
* is not restartable - build a new one.
|
|
64
76
|
*/
|
|
65
77
|
stop(): Promise<void>;
|
|
66
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/applications/worker.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/applications/worker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGxC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC;IACjF,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;IACjF,mBAAmB,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;IACrF,KAAK,CAAC,IAAI,IAAI,CAAC;CAChB;AAED;;;;;GAKG;AACH,8BAAsB,iBAAiB,CACrC,MAAM,SAAS,GAAG,GAAG,GAAG,EACxB,SAAS,SAAS,MAAM,GAAG,EAAE,EAC7B,QAAQ,SAAS,MAAM,GAAG,GAAG,CAC7B,SAAQ,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;IACpD,qMAAqM;IACrM,UAAkB,OAAO,EAAE,yBAAyB,CAAC;IAErD,iGAAiG;IACjG,OAAO,CAAC,cAAc,CAAC,CAAgB;IACvC,+FAA+F;IAC/F,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAC,CAAa;IACrC,OAAO,CAAC,SAAS,CAAS;IAE1B;;;;;;;OAOG;IACM,cAAc,IAAI,MAAM;IASjC;;;OAGG;YACW,aAAa;IAoC3B,kKAAkK;IAClK,OAAO,CAAC,iBAAiB;IAgBzB,kIAAkI;YACpH,YAAY;IAW1B;;;;;OAKG;YACW,eAAe;IAqC7B,OAAO,CAAC,QAAQ;IAsChB;;;;;;OAMG;IACG,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjF;;;;;;;;;OASG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAW5B"}
|
|
@@ -16,6 +16,20 @@ class WorkerApplication extends ignis_kernel_1.RestApplication {
|
|
|
16
16
|
super(...arguments);
|
|
17
17
|
this.isStopped = false;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* `configs.projectRoot` wins, else the host's own working directory - read as
|
|
21
|
+
* `globalThis.process?.cwd?.()`, never a bare `process.cwd()`, because a real browser Worker has no
|
|
22
|
+
* such global and this class ships there. Bound AND shared with `ModuleUtility` (through the
|
|
23
|
+
* purity-safe `ProjectRootRegistry`), the same seam `ServerApplication` gives a socket host. No
|
|
24
|
+
* `node_modules` check here, unlike that host: a browser has no filesystem to check, and `node:fs`
|
|
25
|
+
* would bundle a Node builtin straight into a Worker.
|
|
26
|
+
*/
|
|
27
|
+
getProjectRoot() {
|
|
28
|
+
const projectRoot = this.configs.projectRoot ?? globalThis.process?.cwd?.() ?? '';
|
|
29
|
+
this.bind({ key: ignis_kernel_1.CoreBindings.APPLICATION_PROJECT_ROOT }).toValue(projectRoot);
|
|
30
|
+
core_1.ProjectRootRegistry.set({ projectRoot });
|
|
31
|
+
return projectRoot;
|
|
32
|
+
}
|
|
19
33
|
/**
|
|
20
34
|
* Every failure here is posted back as an `IBffErrorEnvelope`, the failed `postMessage` included:
|
|
21
35
|
* an exception nobody posts leaves the UI waiting out the transport timeout.
|
|
@@ -154,20 +168,21 @@ class WorkerApplication extends ignis_kernel_1.RestApplication {
|
|
|
154
168
|
return this.listenPromise;
|
|
155
169
|
}
|
|
156
170
|
/**
|
|
157
|
-
* The counterpart to `listen()`, and to `ServerApplication.stop()`:
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
171
|
+
* The counterpart to `listen()`, and to `ServerApplication.stop()`: runs the post-stop hooks, then
|
|
172
|
+
* closes every datasource the boot configured. Without it the OPFS exclusive lock a PGlite holds
|
|
173
|
+
* is never released - the next Worker then fails with `NoModificationAllowedError` until a full
|
|
174
|
+
* page reload. The Vite recipe is `import.meta.hot?.dispose(() => application.stop())`.
|
|
161
175
|
*
|
|
162
176
|
* Detaches BEFORE draining, unlike the server: here the listener IS the socket, and a request
|
|
163
|
-
* admitted while
|
|
164
|
-
*
|
|
177
|
+
* admitted while a datasource is closing has nothing left to run against. A stopped application
|
|
178
|
+
* is not restartable - build a new one.
|
|
165
179
|
*/
|
|
166
180
|
async stop() {
|
|
167
181
|
this.isStopped = true;
|
|
168
182
|
this.detachFromScope?.();
|
|
169
183
|
this.detachFromScope = undefined;
|
|
170
184
|
await this.executePostStopHooks();
|
|
185
|
+
await this.closeDataSources();
|
|
171
186
|
this.logger.for(this.stop.name).info('Worker application STOPPED');
|
|
172
187
|
}
|
|
173
188
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/applications/worker.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/applications/worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/envelope/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/envelope/common/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/envelope/common/types.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,gBAAgB,CAAC;IAC1B,+EAA+E;IAC/E,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/envelope/common/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ApplicationError } from '@venizia/ignis-helpers/core';
|
|
2
|
-
import type { IBffErrorEnvelope, IBffRequestEnvelope, IBffResponseEnvelope } from './
|
|
2
|
+
import type { IBffErrorEnvelope, IBffRequestEnvelope, IBffResponseEnvelope } from './common';
|
|
3
3
|
/**
|
|
4
4
|
* Every request built inside the Worker uses this origin. Never `self.location.href`: a `blob:`
|
|
5
5
|
* worker origin is opaque and `new URL(path, blobUrl)` throws, and Hono's `getPath()` mis-parses
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../../src/envelope/encode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../../src/envelope/encode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,0BAA0B,CAAC;AAE5D,+IAA+I;AAC/I,qBAAa,WAAW;IACtB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAEtE;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;IAKpD;;;;;OAKG;WACU,aAAa,CAAC,IAAI,EAAE;QAC/B,OAAO,EAAE,OAAO,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAahC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,mBAAmB,CAAA;KAAE,GAAG,OAAO;WAUzD,cAAc,CAAC,IAAI,EAAE;QAChC,QAAQ,EAAE,QAAQ,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;KACZ,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAajC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,oBAAoB,CAAA;KAAE,GAAG,QAAQ;IAazE;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,GAAG,iBAAiB;IAoB3E,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,iBAAiB,CAAA;KAAE,GAAG,gBAAgB;CAc5E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/envelope/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/envelope/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
|
|
@@ -14,6 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./common"), exports);
|
|
17
18
|
__exportStar(require("./encode"), exports);
|
|
18
|
-
__exportStar(require("./types"), exports);
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/envelope/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/envelope/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,2CAAyB"}
|
|
@@ -8,10 +8,16 @@ export interface IInstallBffFetchOptions {
|
|
|
8
8
|
/** Anything implementing the transport contract, so an in-process transport works in a test. */
|
|
9
9
|
transport: IBffTransport;
|
|
10
10
|
/**
|
|
11
|
-
* Path prefixes the BFF owns, matched
|
|
12
|
-
* to the original `fetch` untouched.
|
|
11
|
+
* Path prefixes the BFF owns, matched on a segment boundary: `/api` claims `/api` and `/api/...`,
|
|
12
|
+
* never `/apix`. Everything else is passed to the original `fetch` untouched.
|
|
13
13
|
*/
|
|
14
14
|
basePath: string | Array<string>;
|
|
15
|
+
/**
|
|
16
|
+
* The origin, or origins, the BFF answers for - the page's own, or an upstream gateway whose
|
|
17
|
+
* calls the BFF stands in for. A request to any other origin goes to the network whatever its path.
|
|
18
|
+
* Unset, only the path decides, so a call to ANY origin under `basePath` is claimed.
|
|
19
|
+
*/
|
|
20
|
+
origin?: string | Array<string>;
|
|
15
21
|
/** Defaults to `globalThis`. */
|
|
16
22
|
carrier?: IFetchCarrier;
|
|
17
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-bridge.d.ts","sourceRoot":"","sources":["../../../src/transport/fetch-bridge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAQpD,KAAK,MAAM,GAAG,OAAO,UAAU,CAAC,KAAK,CAAC;AAEtC,2GAA2G;AAC3G,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,gGAAgG;IAChG,SAAS,EAAE,aAAa,CAAC;IACzB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC,gCAAgC;IAChC,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"fetch-bridge.d.ts","sourceRoot":"","sources":["../../../src/transport/fetch-bridge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAQpD,KAAK,MAAM,GAAG,OAAO,UAAU,CAAC,KAAK,CAAC;AAEtC,2GAA2G;AAC3G,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,gGAAgG;IAChG,SAAS,EAAE,aAAa,CAAC;IACzB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,gCAAgC;IAChC,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAgDD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,uBAAuB,KAAG,CAAC,MAAM,IAAI,CAwD1E,CAAC"}
|
|
@@ -35,7 +35,10 @@ const resolveRequestUrl = (input) => {
|
|
|
35
35
|
return input.url;
|
|
36
36
|
};
|
|
37
37
|
const toPrefixList = (basePath) => {
|
|
38
|
-
|
|
38
|
+
// Trailing slashes trimmed once, so the boundary test below is one comparison and one prefix check.
|
|
39
|
+
const prefixes = (Array.isArray(basePath) ? basePath : [basePath])
|
|
40
|
+
.map(prefix => prefix.replace(/\/+$/, ''))
|
|
41
|
+
.filter(prefix => prefix.length > 0);
|
|
39
42
|
if (prefixes.length === 0) {
|
|
40
43
|
throw (0, core_1.getError)({
|
|
41
44
|
message: '[installBffFetch] Invalid basePath | At least one non-empty path prefix is required',
|
|
@@ -60,6 +63,9 @@ const toPrefixList = (basePath) => {
|
|
|
60
63
|
*/
|
|
61
64
|
const installBffFetch = (opts) => {
|
|
62
65
|
const { transport, basePath } = opts;
|
|
66
|
+
const origins = opts.origin === undefined
|
|
67
|
+
? undefined
|
|
68
|
+
: new Set((Array.isArray(opts.origin) ? opts.origin : [opts.origin]).map(value => new URL(value).origin));
|
|
63
69
|
const carrier = opts.carrier ?? globalThis;
|
|
64
70
|
const prefixes = toPrefixList(basePath);
|
|
65
71
|
const previousFetch = carrier.fetch;
|
|
@@ -70,8 +76,11 @@ const installBffFetch = (opts) => {
|
|
|
70
76
|
}
|
|
71
77
|
const networkFetch = previousFetch.bind(carrier);
|
|
72
78
|
const bridged = async (input, init) => {
|
|
73
|
-
const
|
|
74
|
-
|
|
79
|
+
const url = new URL(resolveRequestUrl(input));
|
|
80
|
+
const { pathname } = url;
|
|
81
|
+
const isOwnOrigin = origins === undefined || origins.has(url.origin);
|
|
82
|
+
const isOwnPath = prefixes.some(prefix => pathname === prefix || pathname.startsWith(`${prefix}/`));
|
|
83
|
+
if (!isOwnOrigin || !isOwnPath) {
|
|
75
84
|
return networkFetch(input, init);
|
|
76
85
|
}
|
|
77
86
|
// Constructed only now, on the branch that owns the request - so the pass-through above never
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-bridge.js","sourceRoot":"","sources":["../../../src/transport/fetch-bridge.ts"],"names":[],"mappings":";;;AAAA,sDAAuD;AAGvD;;;GAGG;AACH,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-bridge.js","sourceRoot":"","sources":["../../../src/transport/fetch-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const DEFAULT_CHANNEL_NAME = "ignis.bff";
|
|
2
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
3
|
+
/** Which part this tab plays. `ELECTING` is the brief window before the lock answers. */
|
|
4
|
+
export declare class BffRoles {
|
|
5
|
+
static readonly ELECTING = "electing";
|
|
6
|
+
static readonly LEADER = "leader";
|
|
7
|
+
static readonly FOLLOWER = "follower";
|
|
8
|
+
}
|
|
9
|
+
export declare class ChannelMessageKinds {
|
|
10
|
+
static readonly REQUEST = "ignis.bff.request";
|
|
11
|
+
static readonly RESPONSE = "ignis.bff.response";
|
|
12
|
+
static readonly ERROR = "ignis.bff.error";
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../src/transport/shared/common/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAChD,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,yFAAyF;AACzF,qBAAa,QAAQ;IACnB,MAAM,CAAC,QAAQ,CAAC,QAAQ,cAAc;IACtC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,QAAQ,cAAc;CACvC;AAED,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,OAAO,uBAAuB;IAC9C,MAAM,CAAC,QAAQ,CAAC,QAAQ,wBAAwB;IAChD,MAAM,CAAC,QAAQ,CAAC,KAAK,qBAAqB;CAC3C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChannelMessageKinds = exports.BffRoles = exports.DEFAULT_TIMEOUT_MS = exports.DEFAULT_CHANNEL_NAME = void 0;
|
|
4
|
+
exports.DEFAULT_CHANNEL_NAME = 'ignis.bff';
|
|
5
|
+
exports.DEFAULT_TIMEOUT_MS = 30_000;
|
|
6
|
+
/** Which part this tab plays. `ELECTING` is the brief window before the lock answers. */
|
|
7
|
+
class BffRoles {
|
|
8
|
+
static { this.ELECTING = 'electing'; }
|
|
9
|
+
static { this.LEADER = 'leader'; }
|
|
10
|
+
static { this.FOLLOWER = 'follower'; }
|
|
11
|
+
}
|
|
12
|
+
exports.BffRoles = BffRoles;
|
|
13
|
+
class ChannelMessageKinds {
|
|
14
|
+
static { this.REQUEST = 'ignis.bff.request'; }
|
|
15
|
+
static { this.RESPONSE = 'ignis.bff.response'; }
|
|
16
|
+
static { this.ERROR = 'ignis.bff.error'; }
|
|
17
|
+
}
|
|
18
|
+
exports.ChannelMessageKinds = ChannelMessageKinds;
|
|
19
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../src/transport/shared/common/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,oBAAoB,GAAG,WAAW,CAAC;AACnC,QAAA,kBAAkB,GAAG,MAAM,CAAC;AAEzC,yFAAyF;AACzF,MAAa,QAAQ;aACH,aAAQ,GAAG,UAAU,CAAC;aACtB,WAAM,GAAG,QAAQ,CAAC;aAClB,aAAQ,GAAG,UAAU,CAAC;;AAHxC,4BAIC;AAED,MAAa,mBAAmB;aACd,YAAO,GAAG,mBAAmB,CAAC;aAC9B,aAAQ,GAAG,oBAAoB,CAAC;aAChC,UAAK,GAAG,iBAAiB,CAAC;;AAH5C,kDAIC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/transport/shared/common/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./constants"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/transport/shared/common/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,0CAAwB"}
|