@qlever-llc/trellis 0.5.1
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 +9 -0
- package/esm/_dnt.polyfills.d.ts +7 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +1 -0
- package/esm/package.json +3 -0
- package/esm/trellis/browser.d.ts +11 -0
- package/esm/trellis/browser.d.ts.map +1 -0
- package/esm/trellis/browser.js +10 -0
- package/esm/trellis/client.d.ts +31 -0
- package/esm/trellis/client.d.ts.map +1 -0
- package/esm/trellis/client.js +13 -0
- package/esm/trellis/codec.d.ts +12 -0
- package/esm/trellis/codec.d.ts.map +1 -0
- package/esm/trellis/codec.js +60 -0
- package/esm/trellis/env.d.ts +2 -0
- package/esm/trellis/env.d.ts.map +1 -0
- package/esm/trellis/env.js +1 -0
- package/esm/trellis/errors/AuthError.d.ts +30 -0
- package/esm/trellis/errors/AuthError.d.ts.map +1 -0
- package/esm/trellis/errors/AuthError.js +65 -0
- package/esm/trellis/errors/KVError.d.ts +31 -0
- package/esm/trellis/errors/KVError.d.ts.map +1 -0
- package/esm/trellis/errors/KVError.js +46 -0
- package/esm/trellis/errors/RemoteError.d.ts +47 -0
- package/esm/trellis/errors/RemoteError.d.ts.map +1 -0
- package/esm/trellis/errors/RemoteError.js +80 -0
- package/esm/trellis/errors/TrellisError.d.ts +16 -0
- package/esm/trellis/errors/TrellisError.d.ts.map +1 -0
- package/esm/trellis/errors/TrellisError.js +15 -0
- package/esm/trellis/errors/ValidationError.d.ts +51 -0
- package/esm/trellis/errors/ValidationError.d.ts.map +1 -0
- package/esm/trellis/errors/ValidationError.js +77 -0
- package/esm/trellis/errors/index.d.ts +38 -0
- package/esm/trellis/errors/index.d.ts.map +1 -0
- package/esm/trellis/errors/index.js +26 -0
- package/esm/trellis/globals.d.ts +2 -0
- package/esm/trellis/globals.d.ts.map +1 -0
- package/esm/trellis/globals.js +8 -0
- package/esm/trellis/helpers.d.ts +12 -0
- package/esm/trellis/helpers.d.ts.map +1 -0
- package/esm/trellis/helpers.js +47 -0
- package/esm/trellis/index.d.ts +11 -0
- package/esm/trellis/index.d.ts.map +1 -0
- package/esm/trellis/index.js +6 -0
- package/esm/trellis/kv.d.ts +67 -0
- package/esm/trellis/kv.d.ts.map +1 -0
- package/esm/trellis/kv.js +326 -0
- package/esm/trellis/models/trellis/TrellisError.d.ts +43 -0
- package/esm/trellis/models/trellis/TrellisError.d.ts.map +1 -0
- package/esm/trellis/models/trellis/TrellisError.js +16 -0
- package/esm/trellis/tasks.d.ts +11 -0
- package/esm/trellis/tasks.d.ts.map +1 -0
- package/esm/trellis/tasks.js +41 -0
- package/esm/trellis/tracing.d.ts +5 -0
- package/esm/trellis/tracing.d.ts.map +1 -0
- package/esm/trellis/tracing.js +7 -0
- package/esm/trellis/trellis.d.ts +117 -0
- package/esm/trellis/trellis.d.ts.map +1 -0
- package/esm/trellis/trellis.js +710 -0
- package/package.json +49 -0
- package/script/_dnt.polyfills.d.ts +7 -0
- package/script/_dnt.polyfills.d.ts.map +1 -0
- package/script/_dnt.polyfills.js +2 -0
- package/script/package.json +3 -0
- package/script/trellis/browser.d.ts +11 -0
- package/script/trellis/browser.d.ts.map +1 -0
- package/script/trellis/browser.js +21 -0
- package/script/trellis/client.d.ts +31 -0
- package/script/trellis/client.d.ts.map +1 -0
- package/script/trellis/client.js +16 -0
- package/script/trellis/codec.d.ts +12 -0
- package/script/trellis/codec.d.ts.map +1 -0
- package/script/trellis/codec.js +66 -0
- package/script/trellis/env.d.ts +2 -0
- package/script/trellis/env.d.ts.map +1 -0
- package/script/trellis/env.js +5 -0
- package/script/trellis/errors/AuthError.d.ts +30 -0
- package/script/trellis/errors/AuthError.d.ts.map +1 -0
- package/script/trellis/errors/AuthError.js +72 -0
- package/script/trellis/errors/KVError.d.ts +31 -0
- package/script/trellis/errors/KVError.d.ts.map +1 -0
- package/script/trellis/errors/KVError.js +53 -0
- package/script/trellis/errors/RemoteError.d.ts +47 -0
- package/script/trellis/errors/RemoteError.d.ts.map +1 -0
- package/script/trellis/errors/RemoteError.js +87 -0
- package/script/trellis/errors/TrellisError.d.ts +16 -0
- package/script/trellis/errors/TrellisError.d.ts.map +1 -0
- package/script/trellis/errors/TrellisError.js +19 -0
- package/script/trellis/errors/ValidationError.d.ts +51 -0
- package/script/trellis/errors/ValidationError.d.ts.map +1 -0
- package/script/trellis/errors/ValidationError.js +84 -0
- package/script/trellis/errors/index.d.ts +38 -0
- package/script/trellis/errors/index.d.ts.map +1 -0
- package/script/trellis/errors/index.js +40 -0
- package/script/trellis/globals.d.ts +2 -0
- package/script/trellis/globals.d.ts.map +1 -0
- package/script/trellis/globals.js +11 -0
- package/script/trellis/helpers.d.ts +12 -0
- package/script/trellis/helpers.d.ts.map +1 -0
- package/script/trellis/helpers.js +54 -0
- package/script/trellis/index.d.ts +11 -0
- package/script/trellis/index.d.ts.map +1 -0
- package/script/trellis/index.js +24 -0
- package/script/trellis/kv.d.ts +67 -0
- package/script/trellis/kv.d.ts.map +1 -0
- package/script/trellis/kv.js +354 -0
- package/script/trellis/models/trellis/TrellisError.d.ts +43 -0
- package/script/trellis/models/trellis/TrellisError.d.ts.map +1 -0
- package/script/trellis/models/trellis/TrellisError.js +22 -0
- package/script/trellis/tasks.d.ts +11 -0
- package/script/trellis/tasks.d.ts.map +1 -0
- package/script/trellis/tasks.js +45 -0
- package/script/trellis/tracing.d.ts +5 -0
- package/script/trellis/tracing.d.ts.map +1 -0
- package/script/trellis/tracing.js +49 -0
- package/script/trellis/trellis.d.ts +117 -0
- package/script/trellis/trellis.d.ts.map +1 -0
- package/script/trellis/trellis.js +715 -0
|
@@ -0,0 +1,354 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.TypedKVEntry = exports.TypedKV = void 0;
|
|
27
|
+
// @ts-nocheck -- svelte-check hits pathological generic instantiation in this file
|
|
28
|
+
const kv_1 = require("@nats-io/kv");
|
|
29
|
+
const trellis_result_1 = require("@qlever-llc/trellis-result");
|
|
30
|
+
const ts_deepmerge_1 = require("ts-deepmerge");
|
|
31
|
+
const value_1 = __importStar(require("typebox/value"));
|
|
32
|
+
const index_js_1 = require("./errors/index.js");
|
|
33
|
+
const helpers_js_1 = require("./helpers.js");
|
|
34
|
+
function externalizeValue(value) {
|
|
35
|
+
if (value instanceof Date) {
|
|
36
|
+
return value.toISOString();
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(value)) {
|
|
39
|
+
return value.map(externalizeValue);
|
|
40
|
+
}
|
|
41
|
+
if (value !== null && typeof value === "object") {
|
|
42
|
+
const out = {};
|
|
43
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
44
|
+
if (entry !== undefined) {
|
|
45
|
+
out[key] = externalizeValue(entry);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
function parseExternalValue(schema, value) {
|
|
53
|
+
if (value_1.default.HasCodec(schema)) {
|
|
54
|
+
return value_1.default.Decode(schema, value);
|
|
55
|
+
}
|
|
56
|
+
return value_1.default.Parse(schema, value);
|
|
57
|
+
}
|
|
58
|
+
function serializeValue(schema, value) {
|
|
59
|
+
return JSON.stringify(value_1.default.Parse(schema, externalizeValue(value)));
|
|
60
|
+
}
|
|
61
|
+
function serializeExternalValue(schema, value) {
|
|
62
|
+
return serializeValue(schema, value);
|
|
63
|
+
}
|
|
64
|
+
class TypedKV {
|
|
65
|
+
constructor(schema, kv) {
|
|
66
|
+
Object.defineProperty(this, "schema", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true,
|
|
69
|
+
writable: true,
|
|
70
|
+
value: schema
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(this, "kv", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: kv
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
static async open(nats, name, schema, options) {
|
|
80
|
+
try {
|
|
81
|
+
const kvm = new kv_1.Kvm(nats);
|
|
82
|
+
const kv = options.bindOnly
|
|
83
|
+
? await kvm.open(name)
|
|
84
|
+
: await kvm.create(name, {
|
|
85
|
+
history: options.history ?? 1,
|
|
86
|
+
ttl: options.ttl ?? 0,
|
|
87
|
+
...(options.maxValueBytes ? { maxValueSize: options.maxValueBytes } : {}),
|
|
88
|
+
});
|
|
89
|
+
const typedKv = new TypedKV(schema, kv);
|
|
90
|
+
return trellis_result_1.Result.ok(typedKv);
|
|
91
|
+
}
|
|
92
|
+
catch (cause) {
|
|
93
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "open", cause }));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async get(key) {
|
|
97
|
+
let s;
|
|
98
|
+
try {
|
|
99
|
+
s = await this.kv.get((0, helpers_js_1.escapeKvKey)(key));
|
|
100
|
+
}
|
|
101
|
+
catch (cause) {
|
|
102
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "get", cause, context: { key } }));
|
|
103
|
+
}
|
|
104
|
+
if (!s) {
|
|
105
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({
|
|
106
|
+
operation: "get",
|
|
107
|
+
context: { key, reason: "not found" },
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
return await createTypedKvEntry(this.schema, this.kv, s);
|
|
111
|
+
}
|
|
112
|
+
async create(key, value) {
|
|
113
|
+
const schema = this.schema;
|
|
114
|
+
const rawValue = value;
|
|
115
|
+
// @ts-expect-error svelte-check hits excessive type instantiation here
|
|
116
|
+
const serialized = serializeExternalValue(schema, rawValue);
|
|
117
|
+
try {
|
|
118
|
+
await this.kv.create((0, helpers_js_1.escapeKvKey)(key), serialized);
|
|
119
|
+
return trellis_result_1.Result.ok(undefined);
|
|
120
|
+
}
|
|
121
|
+
catch (cause) {
|
|
122
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "create", cause, context: { key } }));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async put(key, value) {
|
|
126
|
+
const schema = this.schema;
|
|
127
|
+
const rawValue = value;
|
|
128
|
+
// @ts-expect-error svelte-check hits excessive type instantiation here
|
|
129
|
+
const serialized = serializeExternalValue(schema, rawValue);
|
|
130
|
+
try {
|
|
131
|
+
await this.kv.put((0, helpers_js_1.escapeKvKey)(key), serialized);
|
|
132
|
+
return trellis_result_1.Result.ok(undefined);
|
|
133
|
+
}
|
|
134
|
+
catch (cause) {
|
|
135
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "put", cause, context: { key } }));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async delete(key) {
|
|
139
|
+
try {
|
|
140
|
+
await this.kv.delete((0, helpers_js_1.escapeKvKey)(key));
|
|
141
|
+
return trellis_result_1.Result.ok(undefined);
|
|
142
|
+
}
|
|
143
|
+
catch (cause) {
|
|
144
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "delete", cause, context: { key } }));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async keys(filter = ">") {
|
|
148
|
+
try {
|
|
149
|
+
return trellis_result_1.Result.ok(await this.kv.keys(filter));
|
|
150
|
+
}
|
|
151
|
+
catch (cause) {
|
|
152
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "keys", cause, context: { filter } }));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async status() {
|
|
156
|
+
try {
|
|
157
|
+
const status = await this.kv.status();
|
|
158
|
+
return trellis_result_1.Result.ok({ values: status.values });
|
|
159
|
+
}
|
|
160
|
+
catch (cause) {
|
|
161
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "status", cause }));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
exports.TypedKV = TypedKV;
|
|
166
|
+
class TypedKVEntry {
|
|
167
|
+
constructor(schema, kv, entry, value) {
|
|
168
|
+
Object.defineProperty(this, "schema", {
|
|
169
|
+
enumerable: true,
|
|
170
|
+
configurable: true,
|
|
171
|
+
writable: true,
|
|
172
|
+
value: schema
|
|
173
|
+
});
|
|
174
|
+
Object.defineProperty(this, "kv", {
|
|
175
|
+
enumerable: true,
|
|
176
|
+
configurable: true,
|
|
177
|
+
writable: true,
|
|
178
|
+
value: kv
|
|
179
|
+
});
|
|
180
|
+
Object.defineProperty(this, "entry", {
|
|
181
|
+
enumerable: true,
|
|
182
|
+
configurable: true,
|
|
183
|
+
writable: true,
|
|
184
|
+
value: entry
|
|
185
|
+
});
|
|
186
|
+
Object.defineProperty(this, "value", {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
configurable: true,
|
|
189
|
+
writable: true,
|
|
190
|
+
value: void 0
|
|
191
|
+
});
|
|
192
|
+
// @ts-expect-error svelte-check hits excessive type instantiation on assignment
|
|
193
|
+
this.value = value;
|
|
194
|
+
}
|
|
195
|
+
static async create(schema, kv, entry) {
|
|
196
|
+
return await createTypedKvEntry(schema, kv, entry);
|
|
197
|
+
}
|
|
198
|
+
get key() {
|
|
199
|
+
return (0, helpers_js_1.decodeSubject)(this.entry.key);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Watch this KV entry for changes.
|
|
203
|
+
*
|
|
204
|
+
* @param callback - Function called when the entry changes
|
|
205
|
+
* @param opts - Watch options (e.g., includeDeletes)
|
|
206
|
+
* @returns A function to stop watching
|
|
207
|
+
*/
|
|
208
|
+
async watch(callback, opts) {
|
|
209
|
+
const watcher = await this.kv.watch({
|
|
210
|
+
key: this.entry.key,
|
|
211
|
+
include: opts?.includeDeletes ? "history" : "updates",
|
|
212
|
+
});
|
|
213
|
+
const abortController = new AbortController();
|
|
214
|
+
// Start the async iteration in the background
|
|
215
|
+
(async () => {
|
|
216
|
+
for await (const entry of watcher) {
|
|
217
|
+
if (abortController.signal.aborted)
|
|
218
|
+
break;
|
|
219
|
+
if (entry.operation === "DEL" || entry.operation === "PURGE") {
|
|
220
|
+
if (opts?.includeDeletes) {
|
|
221
|
+
callback({
|
|
222
|
+
type: "delete",
|
|
223
|
+
key: (0, helpers_js_1.decodeSubject)(entry.key),
|
|
224
|
+
revision: entry.revision,
|
|
225
|
+
timestamp: entry.created,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
let validated;
|
|
231
|
+
try {
|
|
232
|
+
const json = entry.json();
|
|
233
|
+
validated = parseExternalValue(this.schema, json);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
try {
|
|
237
|
+
await this.kv.delete(entry.key, {
|
|
238
|
+
previousSeq: entry.revision,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Best-effort cleanup of invalid entries.
|
|
243
|
+
}
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
callback({
|
|
247
|
+
type: "update",
|
|
248
|
+
key: (0, helpers_js_1.decodeSubject)(entry.key),
|
|
249
|
+
value: validated,
|
|
250
|
+
revision: entry.revision,
|
|
251
|
+
timestamp: entry.created,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
})();
|
|
256
|
+
return () => {
|
|
257
|
+
abortController.abort();
|
|
258
|
+
watcher.stop();
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
async merge(value, vcc) {
|
|
262
|
+
// @ts-expect-error svelte-check hits excessive type instantiation here
|
|
263
|
+
const mergedData = (0, ts_deepmerge_1.merge)(this.value, value);
|
|
264
|
+
const schema = this.schema;
|
|
265
|
+
const mergedRawValue = mergedData;
|
|
266
|
+
// @ts-expect-error svelte-check hits excessive type instantiation here
|
|
267
|
+
const mergeResult = trellis_result_1.Result.try(() => serializeExternalValue(schema, mergedRawValue));
|
|
268
|
+
if (mergeResult.isErr()) {
|
|
269
|
+
const cause = mergeResult.error.cause;
|
|
270
|
+
if (cause instanceof value_1.ParseError) {
|
|
271
|
+
const errors = value_1.default.Errors(schema, externalizeValue(mergedData));
|
|
272
|
+
return trellis_result_1.Result.err(new index_js_1.ValidationError({ errors, cause }));
|
|
273
|
+
}
|
|
274
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "merge", cause: mergeResult.error, context: { key: this.key } }));
|
|
275
|
+
}
|
|
276
|
+
return this.put(mergedData, vcc);
|
|
277
|
+
}
|
|
278
|
+
async put(value, vcc) {
|
|
279
|
+
const schema = this.schema;
|
|
280
|
+
const serialized = serializeValue(schema, value);
|
|
281
|
+
try {
|
|
282
|
+
await this.kv.put(this.entry.key, serialized, {
|
|
283
|
+
previousSeq: vcc ? this.entry.revision : undefined,
|
|
284
|
+
});
|
|
285
|
+
return trellis_result_1.Result.ok(undefined);
|
|
286
|
+
}
|
|
287
|
+
catch (cause) {
|
|
288
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "put", cause, context: { key: this.key } }));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
async delete(vcc) {
|
|
292
|
+
try {
|
|
293
|
+
await this.kv.delete(this.entry.key, {
|
|
294
|
+
previousSeq: vcc ? this.entry.revision : undefined,
|
|
295
|
+
});
|
|
296
|
+
return trellis_result_1.Result.ok(undefined);
|
|
297
|
+
}
|
|
298
|
+
catch (cause) {
|
|
299
|
+
return trellis_result_1.Result.err(new index_js_1.KVError({ operation: "delete", cause, context: { key: this.key } }));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
exports.TypedKVEntry = TypedKVEntry;
|
|
304
|
+
async function createTypedKvEntry(schema, kv, entry) {
|
|
305
|
+
async function deleteInvalidEntry(reason) {
|
|
306
|
+
try {
|
|
307
|
+
await kv.delete(entry.key, {
|
|
308
|
+
previousSeq: entry.revision,
|
|
309
|
+
});
|
|
310
|
+
return {
|
|
311
|
+
key: (0, helpers_js_1.decodeSubject)(entry.key),
|
|
312
|
+
revision: entry.revision,
|
|
313
|
+
invalidEntryDeleted: true,
|
|
314
|
+
invalidEntryReason: reason,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
catch (cause) {
|
|
318
|
+
return {
|
|
319
|
+
key: (0, helpers_js_1.decodeSubject)(entry.key),
|
|
320
|
+
revision: entry.revision,
|
|
321
|
+
invalidEntryDeleted: false,
|
|
322
|
+
invalidEntryDeleteError: cause instanceof Error ? cause.message : String(cause),
|
|
323
|
+
invalidEntryReason: reason,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const jsonResult = trellis_result_1.Result.try(() => entry.json());
|
|
328
|
+
if (jsonResult.isErr()) {
|
|
329
|
+
const context = await deleteInvalidEntry(`decode failed: ${jsonResult.error.message}`);
|
|
330
|
+
return trellis_result_1.Result.err(new index_js_1.ValidationError({
|
|
331
|
+
errors: [{ path: "", message: `Failed to decode KV value: ${jsonResult.error.message}` }],
|
|
332
|
+
cause: jsonResult.error,
|
|
333
|
+
context,
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
const json = jsonResult.take();
|
|
337
|
+
const parseResult = trellis_result_1.Result.try(() => parseExternalValue(schema, json));
|
|
338
|
+
if (parseResult.isErr()) {
|
|
339
|
+
const cause = parseResult.error.cause;
|
|
340
|
+
if (cause instanceof value_1.ParseError) {
|
|
341
|
+
const errors = value_1.default.Errors(schema, json);
|
|
342
|
+
const context = await deleteInvalidEntry("schema parse failed");
|
|
343
|
+
return trellis_result_1.Result.err(new index_js_1.ValidationError({ errors, cause, context }));
|
|
344
|
+
}
|
|
345
|
+
const context = await deleteInvalidEntry(parseResult.error.message);
|
|
346
|
+
return trellis_result_1.Result.err(new index_js_1.ValidationError({
|
|
347
|
+
errors: [{ path: "", message: parseResult.error.message }],
|
|
348
|
+
cause: parseResult.error,
|
|
349
|
+
context,
|
|
350
|
+
}));
|
|
351
|
+
}
|
|
352
|
+
const typedEntry = new TypedKVEntry(schema, kv, entry, parseResult.take());
|
|
353
|
+
return trellis_result_1.Result.ok(typedEntry);
|
|
354
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Type, { type StaticDecode } from "typebox";
|
|
2
|
+
/**
|
|
3
|
+
* Discriminated union schema for all possible Trellis error types.
|
|
4
|
+
* These errors can be serialized and sent over RPC.
|
|
5
|
+
* Note: RemoteError is not included here as it's a local wrapper, not a serializable error type.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TrellisErrorDataSchema: Type.TUnion<[Type.TObject<{
|
|
8
|
+
id: Type.TString;
|
|
9
|
+
type: Type.TLiteral<"UnexpectedError">;
|
|
10
|
+
message: Type.TString;
|
|
11
|
+
context: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
12
|
+
traceId: Type.TOptional<Type.TString>;
|
|
13
|
+
}>, Type.TObject<{
|
|
14
|
+
id: Type.TString;
|
|
15
|
+
type: Type.TLiteral<"ValidationError">;
|
|
16
|
+
message: Type.TString;
|
|
17
|
+
issues: Type.TArray<Type.TObject<{
|
|
18
|
+
path: Type.TString;
|
|
19
|
+
message: Type.TString;
|
|
20
|
+
}>>;
|
|
21
|
+
context: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
22
|
+
traceId: Type.TOptional<Type.TString>;
|
|
23
|
+
}>, Type.TObject<{
|
|
24
|
+
id: Type.TString;
|
|
25
|
+
type: Type.TLiteral<"AuthError">;
|
|
26
|
+
message: Type.TString;
|
|
27
|
+
reason: Type.TUnion<[Type.TLiteral<"invalid_request">, Type.TLiteral<"missing_session_key">, Type.TLiteral<"missing_proof">, Type.TLiteral<"session_not_found">, Type.TLiteral<"session_expired">, Type.TLiteral<"invalid_signature">, Type.TLiteral<"user_not_found">, Type.TLiteral<"user_inactive">, Type.TLiteral<"unknown_service">, Type.TLiteral<"service_disabled">, Type.TLiteral<"iat_out_of_range">, Type.TLiteral<"invalid_binding_token">, Type.TLiteral<"session_corrupted">, Type.TLiteral<"session_already_bound">, Type.TLiteral<"authtoken_already_used">, Type.TLiteral<"oauth_session_key_mismatch">, Type.TLiteral<"service_role_on_user">, Type.TLiteral<"reply_subject_mismatch">, Type.TLiteral<"insufficient_permissions">, Type.TLiteral<"forbidden">]>;
|
|
28
|
+
context: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
29
|
+
traceId: Type.TOptional<Type.TString>;
|
|
30
|
+
}>, Type.TObject<{
|
|
31
|
+
id: Type.TString;
|
|
32
|
+
type: Type.TLiteral<"KVError">;
|
|
33
|
+
message: Type.TString;
|
|
34
|
+
operation: Type.TOptional<Type.TString>;
|
|
35
|
+
context: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
36
|
+
traceId: Type.TOptional<Type.TString>;
|
|
37
|
+
}>]>;
|
|
38
|
+
/**
|
|
39
|
+
* Type for validated Trellis error data.
|
|
40
|
+
* This is a discriminated union that enables type narrowing based on the `type` field.
|
|
41
|
+
*/
|
|
42
|
+
export type TrellisErrorData = StaticDecode<typeof TrellisErrorDataSchema>;
|
|
43
|
+
//# sourceMappingURL=TrellisError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrellisError.d.ts","sourceRoot":"","sources":["../../../../src/trellis/models/trellis/TrellisError.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAMlD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAKjC,CAAC;AAEH;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TrellisErrorDataSchema = void 0;
|
|
7
|
+
const typebox_1 = __importDefault(require("typebox"));
|
|
8
|
+
const mod_js_1 = require("@qlever-llc/trellis-result");
|
|
9
|
+
const ValidationError_js_1 = require("../../errors/ValidationError.js");
|
|
10
|
+
const AuthError_js_1 = require("../../errors/AuthError.js");
|
|
11
|
+
const KVError_js_1 = require("../../errors/KVError.js");
|
|
12
|
+
/**
|
|
13
|
+
* Discriminated union schema for all possible Trellis error types.
|
|
14
|
+
* These errors can be serialized and sent over RPC.
|
|
15
|
+
* Note: RemoteError is not included here as it's a local wrapper, not a serializable error type.
|
|
16
|
+
*/
|
|
17
|
+
exports.TrellisErrorDataSchema = typebox_1.default.Union([
|
|
18
|
+
mod_js_1.UnexpectedErrorDataSchema,
|
|
19
|
+
ValidationError_js_1.ValidationErrorDataSchema,
|
|
20
|
+
AuthError_js_1.AuthErrorDataSchema,
|
|
21
|
+
KVError_js_1.KVErrorDataSchema,
|
|
22
|
+
]);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AsyncResult, type BaseError } from "@qlever-llc/trellis-result";
|
|
2
|
+
import type { Logger } from "pino";
|
|
3
|
+
export declare class TrellisTasks {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(opts: {
|
|
6
|
+
log?: Logger;
|
|
7
|
+
});
|
|
8
|
+
add<E extends BaseError>(name: string, task: AsyncResult<void, E>): void;
|
|
9
|
+
wait(): AsyncResult<void, BaseError>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/trellis/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAU,MAAM,4BAA4B,CAAC;AACjF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,qBAAa,YAAY;;gBAKX,IAAI,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAOlC,GAAG,CAAC,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAejE,IAAI,IAAI,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC;CAGrC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _TrellisTasks_tasks, _TrellisTasks_log;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.TrellisTasks = void 0;
|
|
16
|
+
const trellis_result_1 = require("@qlever-llc/trellis-result");
|
|
17
|
+
const globals_js_1 = require("./globals.js");
|
|
18
|
+
class TrellisTasks {
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
_TrellisTasks_tasks.set(this, {});
|
|
21
|
+
_TrellisTasks_log.set(this, void 0);
|
|
22
|
+
__classPrivateFieldSet(this, _TrellisTasks_log, opts.log ?? globals_js_1.logger, "f");
|
|
23
|
+
}
|
|
24
|
+
/*
|
|
25
|
+
* Add a task to the task queue
|
|
26
|
+
*/
|
|
27
|
+
add(name, task) {
|
|
28
|
+
if (name in __classPrivateFieldGet(this, _TrellisTasks_tasks, "f")) {
|
|
29
|
+
__classPrivateFieldGet(this, _TrellisTasks_log, "f").error({ name }, "Task already running?");
|
|
30
|
+
throw new Error(`Task ${name} already running`);
|
|
31
|
+
}
|
|
32
|
+
__classPrivateFieldGet(this, _TrellisTasks_log, "f").debug({ name }, "Added task");
|
|
33
|
+
__classPrivateFieldGet(this, _TrellisTasks_tasks, "f")[name] = task.then((r) => {
|
|
34
|
+
if (trellis_result_1.Result.isErr(r)) {
|
|
35
|
+
__classPrivateFieldGet(this, _TrellisTasks_log, "f").error(r, "Task encountered a runtime error");
|
|
36
|
+
}
|
|
37
|
+
return r;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
wait() {
|
|
41
|
+
return trellis_result_1.AsyncResult.any(Object.values(__classPrivateFieldGet(this, _TrellisTasks_tasks, "f")));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.TrellisTasks = TrellisTasks;
|
|
45
|
+
_TrellisTasks_tasks = new WeakMap(), _TrellisTasks_log = new WeakMap();
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import "../_dnt.polyfills.js";
|
|
2
|
+
export type { HeaderCarrier, NatsHeadersLike } from "@qlever-llc/trellis-telemetry";
|
|
3
|
+
export { configureErrorTraceId, context, createMapCarrier, createNatsHeaderCarrier, extractTraceContext, getActiveSpan, getTrellisTracer as getTracer, injectTraceContext, SpanKind, SpanStatusCode, startClientSpan, startServerSpan, trace, withSpan, withSpanAsync } from "@qlever-llc/trellis-telemetry";
|
|
4
|
+
export declare function initTracing(serviceName: string): void;
|
|
5
|
+
//# sourceMappingURL=tracing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../src/trellis/tracing.ts"],"names":[],"mappings":"AAEA,OAAO,sBAAsB,CAAC;AAE9B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAC,qBAAqB,EAC3B,OAAO,EACP,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EAAC,gBAAgB,IAAI,SAAS,EAC3C,kBAAkB,EAClB,QAAQ,EACR,cAAc,EAAC,eAAe,EAAE,eAAe,EAC/C,KAAK,EACL,QAAQ,EACR,aAAa,EACd,MAAM,+BAA+B,CAAC;AACvC,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAErD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.withSpanAsync = exports.withSpan = exports.trace = exports.startServerSpan = exports.startClientSpan = exports.SpanStatusCode = exports.SpanKind = exports.injectTraceContext = exports.getTracer = exports.getActiveSpan = exports.extractTraceContext = exports.createNatsHeaderCarrier = exports.createMapCarrier = exports.context = exports.configureErrorTraceId = void 0;
|
|
27
|
+
exports.initTracing = initTracing;
|
|
28
|
+
// Keep this subpath for Trellis-specific tracing convenience without exposing
|
|
29
|
+
// telemetry from the root `@qlever-llc/trellis` package surface.
|
|
30
|
+
require("../_dnt.polyfills.js");
|
|
31
|
+
var trellis_telemetry_1 = require("@qlever-llc/trellis-telemetry");
|
|
32
|
+
Object.defineProperty(exports, "configureErrorTraceId", { enumerable: true, get: function () { return trellis_telemetry_1.configureErrorTraceId; } });
|
|
33
|
+
Object.defineProperty(exports, "context", { enumerable: true, get: function () { return trellis_telemetry_1.context; } });
|
|
34
|
+
Object.defineProperty(exports, "createMapCarrier", { enumerable: true, get: function () { return trellis_telemetry_1.createMapCarrier; } });
|
|
35
|
+
Object.defineProperty(exports, "createNatsHeaderCarrier", { enumerable: true, get: function () { return trellis_telemetry_1.createNatsHeaderCarrier; } });
|
|
36
|
+
Object.defineProperty(exports, "extractTraceContext", { enumerable: true, get: function () { return trellis_telemetry_1.extractTraceContext; } });
|
|
37
|
+
Object.defineProperty(exports, "getActiveSpan", { enumerable: true, get: function () { return trellis_telemetry_1.getActiveSpan; } });
|
|
38
|
+
Object.defineProperty(exports, "getTracer", { enumerable: true, get: function () { return trellis_telemetry_1.getTrellisTracer; } });
|
|
39
|
+
Object.defineProperty(exports, "injectTraceContext", { enumerable: true, get: function () { return trellis_telemetry_1.injectTraceContext; } });
|
|
40
|
+
Object.defineProperty(exports, "SpanKind", { enumerable: true, get: function () { return trellis_telemetry_1.SpanKind; } });
|
|
41
|
+
Object.defineProperty(exports, "SpanStatusCode", { enumerable: true, get: function () { return trellis_telemetry_1.SpanStatusCode; } });
|
|
42
|
+
Object.defineProperty(exports, "startClientSpan", { enumerable: true, get: function () { return trellis_telemetry_1.startClientSpan; } });
|
|
43
|
+
Object.defineProperty(exports, "startServerSpan", { enumerable: true, get: function () { return trellis_telemetry_1.startServerSpan; } });
|
|
44
|
+
Object.defineProperty(exports, "trace", { enumerable: true, get: function () { return trellis_telemetry_1.trace; } });
|
|
45
|
+
Object.defineProperty(exports, "withSpan", { enumerable: true, get: function () { return trellis_telemetry_1.withSpan; } });
|
|
46
|
+
Object.defineProperty(exports, "withSpanAsync", { enumerable: true, get: function () { return trellis_telemetry_1.withSpanAsync; } });
|
|
47
|
+
function initTracing(serviceName) {
|
|
48
|
+
void Promise.resolve().then(() => __importStar(require("@qlever-llc/trellis-telemetry"))).then((mod) => mod.initTracing(serviceName));
|
|
49
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type NatsConnection } from "@nats-io/nats-core";
|
|
2
|
+
import type { InferSchemaType, TrellisAPI } from "@qlever-llc/trellis-contracts";
|
|
3
|
+
import { AsyncResult, type BaseError, type MaybeAsync, Result } from "@qlever-llc/trellis-result";
|
|
4
|
+
import { API as trellisCoreApi } from "@qlever-llc/trellis-sdk-core";
|
|
5
|
+
import type { Logger } from "pino";
|
|
6
|
+
import { type TrellisErrorInstance, UnexpectedError, ValidationError } from "./errors/index.js";
|
|
7
|
+
import { RemoteError } from "./errors/RemoteError.js";
|
|
8
|
+
type SessionUser = {
|
|
9
|
+
id: string;
|
|
10
|
+
origin: string;
|
|
11
|
+
active: boolean;
|
|
12
|
+
name: string;
|
|
13
|
+
email: string;
|
|
14
|
+
image?: string;
|
|
15
|
+
capabilities: string[];
|
|
16
|
+
lastLogin?: string;
|
|
17
|
+
};
|
|
18
|
+
export type TrellisSigner = (data: Uint8Array) => Promise<Uint8Array> | Uint8Array;
|
|
19
|
+
export type TrellisAuth = {
|
|
20
|
+
sessionKey: string;
|
|
21
|
+
sign: TrellisSigner;
|
|
22
|
+
};
|
|
23
|
+
type AnyTrellisAPI = TrellisAPI;
|
|
24
|
+
type MethodsOf<TA extends AnyTrellisAPI> = keyof TA["rpc"] & string;
|
|
25
|
+
type EventsOf<TA extends AnyTrellisAPI> = keyof TA["events"] & string;
|
|
26
|
+
type MethodInputOf<TA extends AnyTrellisAPI, M extends MethodsOf<TA>> = InferSchemaType<TA["rpc"][M]["input"]>;
|
|
27
|
+
type MethodOutputOf<TA extends AnyTrellisAPI, M extends MethodsOf<TA>> = InferSchemaType<TA["rpc"][M]["output"]>;
|
|
28
|
+
type EventOf<TA extends AnyTrellisAPI, E extends EventsOf<TA>> = InferSchemaType<TA["events"][E]["event"]>;
|
|
29
|
+
type EventPayloadOf<TA extends AnyTrellisAPI, E extends EventsOf<TA>> = Omit<EventOf<TA, E>, "header">;
|
|
30
|
+
type NoResponderRetryOpts = {
|
|
31
|
+
maxAttempts?: number;
|
|
32
|
+
baseDelayMs?: number;
|
|
33
|
+
};
|
|
34
|
+
type TrellisOpts<TA extends AnyTrellisAPI> = {
|
|
35
|
+
log?: Logger;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
stream?: string;
|
|
38
|
+
noResponderRetry?: NoResponderRetryOpts;
|
|
39
|
+
api?: TA;
|
|
40
|
+
authBypassMethods?: string[];
|
|
41
|
+
};
|
|
42
|
+
type RequestOpts = {
|
|
43
|
+
timeout?: number;
|
|
44
|
+
};
|
|
45
|
+
type HandlerFn<TA extends AnyTrellisAPI, M extends MethodsOf<TA>> = (m: MethodInputOf<TA, M>, context: {
|
|
46
|
+
user: SessionUser;
|
|
47
|
+
sessionKey: string;
|
|
48
|
+
}) => Promise<Result<MethodOutputOf<TA, M>, TrellisErrorInstance>>;
|
|
49
|
+
type DeepRecord<T> = {
|
|
50
|
+
[k: string]: T | DeepRecord<T>;
|
|
51
|
+
};
|
|
52
|
+
export declare class Trellis<TA extends AnyTrellisAPI = typeof trellisCoreApi> {
|
|
53
|
+
#private;
|
|
54
|
+
readonly name: string;
|
|
55
|
+
readonly timeout: number;
|
|
56
|
+
readonly stream: string;
|
|
57
|
+
private nats;
|
|
58
|
+
private js;
|
|
59
|
+
protected auth: TrellisAuth;
|
|
60
|
+
readonly api: TA;
|
|
61
|
+
constructor(name: string, // Must be unique for a service
|
|
62
|
+
nats: NatsConnection, auth: TrellisAuth, opts?: TrellisOpts<TA>);
|
|
63
|
+
/**
|
|
64
|
+
* Returns the underlying NATS connection.
|
|
65
|
+
*/
|
|
66
|
+
get natsConnection(): NatsConnection;
|
|
67
|
+
/**
|
|
68
|
+
* Makes an authenticated request to a Trellis RPC method.
|
|
69
|
+
*
|
|
70
|
+
* @template M The specific RPC method being called.
|
|
71
|
+
* @param method The name of the RPC method to call.
|
|
72
|
+
* @param input The input data for the method, conforming to its schema.
|
|
73
|
+
* @param opts Optional request-specific options.
|
|
74
|
+
* @returns A promise that resolves with a `Result` containing either the method's
|
|
75
|
+
* output or an error.
|
|
76
|
+
* @returns A `Result` object:
|
|
77
|
+
* ok: A validated reponse of method M
|
|
78
|
+
* err: RemoteError | ValidationError | UnexpectedError
|
|
79
|
+
*/
|
|
80
|
+
request<M extends MethodsOf<TA>>(method: M, input: MethodInputOf<TA, M>, opts?: RequestOpts): Promise<Result<MethodOutputOf<TA, M>, RemoteError | ValidationError | UnexpectedError>>;
|
|
81
|
+
mount<M extends MethodsOf<TA>>(method: M, fn: HandlerFn<TA, M>): Promise<void>;
|
|
82
|
+
publish<E extends EventsOf<TA>>(event: E, data: EventPayloadOf<TA, E>): Promise<Result<void, ValidationError | UnexpectedError>>;
|
|
83
|
+
event<E extends EventsOf<TA>>(event: E, subjectData: DeepRecord<string | number | boolean>, fn: (m: EventOf<TA, E>) => MaybeAsync<void, BaseError>): Promise<Result<void, ValidationError | UnexpectedError>>;
|
|
84
|
+
wait(): AsyncResult<void, BaseError>;
|
|
85
|
+
template(subject: string, data: unknown, allowWildcards?: boolean): Result<string, ValidationError>;
|
|
86
|
+
}
|
|
87
|
+
type TrellisServerOpts<TA extends AnyTrellisAPI> = Omit<TrellisOpts<TA>, "api"> & {
|
|
88
|
+
api: TA;
|
|
89
|
+
version?: string;
|
|
90
|
+
};
|
|
91
|
+
export declare class TrellisServer<TA extends AnyTrellisAPI = AnyTrellisAPI> extends Trellis<TA> {
|
|
92
|
+
#private;
|
|
93
|
+
private constructor();
|
|
94
|
+
/**
|
|
95
|
+
* Creates an authenticated TrellisServer instance.
|
|
96
|
+
*
|
|
97
|
+
* Services connect to NATS using the session-key auth flow (see ADR):
|
|
98
|
+
* - NATS `auth_token` (aka `token`) is a JSON string `{ v: 1, sessionKey, iat, sig }`
|
|
99
|
+
* - `sig` signs SHA-256(`nats-connect:${iat}`) with the session key
|
|
100
|
+
* - `inboxPrefix` MUST be `_INBOX.${sessionKey.slice(0, 16)}`
|
|
101
|
+
*
|
|
102
|
+
* @param name Unique name for this service
|
|
103
|
+
* @param nats Existing NATS connection (already authenticated)
|
|
104
|
+
* @param auth Service session-key credentials
|
|
105
|
+
* @param opts Optional server options
|
|
106
|
+
* @returns An authenticated TrellisServer instance
|
|
107
|
+
*/
|
|
108
|
+
static create<TA extends AnyTrellisAPI = AnyTrellisAPI>(name: string, nats: NatsConnection, auth: TrellisAuth, opts: TrellisServerOpts<TA>): TrellisServer<TA>;
|
|
109
|
+
/**
|
|
110
|
+
* Stops the server by clearing refresh timers and draining the NATS connection.
|
|
111
|
+
* Draining allows in-flight messages to complete before closing the connection.
|
|
112
|
+
* This method is idempotent and can be called multiple times safely.
|
|
113
|
+
*/
|
|
114
|
+
stop(): Promise<void>;
|
|
115
|
+
}
|
|
116
|
+
export {};
|
|
117
|
+
//# sourceMappingURL=trellis.d.ts.map
|