target-supabase-sdk 0.2.15 → 0.2.17
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 +20 -0
- package/dist/browser.d.ts +6 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -1
- package/dist/chunks/{task-queue-DCY_0Qj0.js → task-queue-DufG7PlX.js} +295 -121
- package/dist/chunks/task-queue-DufG7PlX.js.map +1 -0
- package/dist/config/config.api.d.ts +61 -0
- package/dist/config/config.api.d.ts.map +1 -0
- package/dist/{service → config}/config.interface.d.ts +1 -3
- package/dist/config/config.interface.d.ts.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/node/runtime-state/service-runtime-state.types.d.ts +1 -1
- package/dist/node/runtime-state/service-runtime-state.types.d.ts.map +1 -1
- package/dist/node/service-guard/registry-slot-guard-step.d.ts +1 -1
- package/dist/node/service-guard/registry-slot-guard-step.d.ts.map +1 -1
- package/dist/node/service-guard/service-guard.interface.d.ts +1 -1
- package/dist/node/service-guard/service-guard.interface.d.ts.map +1 -1
- package/dist/node/service-host/claim-registry-slot.d.ts +1 -1
- package/dist/node/service-host/claim-registry-slot.d.ts.map +1 -1
- package/dist/node/service-host/service-host.d.ts +1 -1
- package/dist/node/service-host/service-host.d.ts.map +1 -1
- package/dist/node/service-host/single-process-service.d.ts +1 -1
- package/dist/node/service-host/single-process-service.d.ts.map +1 -1
- package/dist/node.d.ts +2 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +211 -6
- package/dist/node.js.map +1 -1
- package/dist/service/index.d.ts +5 -10
- package/dist/service/index.d.ts.map +1 -1
- package/dist/service/registry/index.d.ts +14 -0
- package/dist/service/registry/index.d.ts.map +1 -0
- package/dist/service/{registry-lifecycle.d.ts → registry/registry-lifecycle.d.ts} +1 -1
- package/dist/service/registry/registry-lifecycle.d.ts.map +1 -0
- package/dist/service/{config.api.d.ts → registry/registry.api.d.ts} +5 -65
- package/dist/service/registry/registry.api.d.ts.map +1 -0
- package/dist/service/registry/registry.constant.d.ts +23 -0
- package/dist/service/registry/registry.constant.d.ts.map +1 -0
- package/dist/service/registry/registry.interface.d.ts +15 -0
- package/dist/service/registry/registry.interface.d.ts.map +1 -0
- package/dist/service/{registry.service.d.ts → registry/registry.service.d.ts} +23 -15
- package/dist/service/registry/registry.service.d.ts.map +1 -0
- package/dist/service/service.interface.d.ts +0 -10
- package/dist/service/service.interface.d.ts.map +1 -1
- package/dist/shared/media/index.d.ts +14 -0
- package/dist/shared/media/index.d.ts.map +1 -0
- package/dist/shared/media/media.build.d.ts +20 -0
- package/dist/shared/media/media.build.d.ts.map +1 -0
- package/dist/shared/media/media.interface.d.ts +38 -0
- package/dist/shared/media/media.interface.d.ts.map +1 -0
- package/dist/shared/media/media.mime.d.ts +4 -0
- package/dist/shared/media/media.mime.d.ts.map +1 -0
- package/dist/shared/media/media.name.d.ts +6 -0
- package/dist/shared/media/media.name.d.ts.map +1 -0
- package/dist/shared/media/media.query.d.ts +8 -0
- package/dist/shared/media/media.query.d.ts.map +1 -0
- package/dist/shared/media/node/index.d.ts +9 -0
- package/dist/shared/media/node/index.d.ts.map +1 -0
- package/dist/shared/media/node/media.access.d.ts +40 -0
- package/dist/shared/media/node/media.access.d.ts.map +1 -0
- package/dist/shared/media/node/media.service.d.ts +30 -0
- package/dist/shared/media/node/media.service.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/browser.ts +21 -9
- package/src/config/config.api.ts +72 -0
- package/src/{service → config}/config.interface.ts +1 -4
- package/src/config/index.ts +9 -0
- package/src/node/runtime-state/create-service-runtime-state-store.ts +1 -1
- package/src/node/runtime-state/service-runtime-state.types.ts +1 -1
- package/src/node/service-guard/registry-slot-guard-step.ts +4 -1
- package/src/node/service-guard/run-service-guard-tick.ts +1 -1
- package/src/node/service-guard/service-guard.interface.ts +1 -1
- package/src/node/service-host/claim-registry-slot.ts +2 -2
- package/src/node/service-host/service-host.ts +2 -2
- package/src/node/service-host/single-process-service.ts +1 -1
- package/src/node.ts +13 -0
- package/src/service/index.ts +30 -40
- package/src/service/registry/index.ts +65 -0
- package/src/service/{registry-lifecycle.ts → registry/registry-lifecycle.ts} +3 -3
- package/src/service/{config.api.ts → registry/registry.api.ts} +6 -80
- package/src/service/registry/registry.constant.ts +17 -0
- package/src/service/registry/registry.interface.ts +16 -0
- package/src/service/{registry.service.ts → registry/registry.service.ts} +66 -65
- package/src/service/service.interface.ts +0 -12
- package/src/shared/media/README.md +109 -0
- package/src/shared/media/index.ts +19 -0
- package/src/shared/media/media.build.ts +69 -0
- package/src/shared/media/media.interface.ts +45 -0
- package/src/shared/media/media.mime.ts +64 -0
- package/src/shared/media/media.name.ts +33 -0
- package/src/shared/media/media.query.ts +13 -0
- package/src/shared/media/node/index.ts +13 -0
- package/src/shared/media/node/media.access.ts +148 -0
- package/src/shared/media/node/media.service.ts +129 -0
- package/dist/chunks/task-queue-DCY_0Qj0.js.map +0 -1
- package/dist/service/config.api.d.ts.map +0 -1
- package/dist/service/config.interface.d.ts.map +0 -1
- package/dist/service/registry-lifecycle.d.ts.map +0 -1
- package/dist/service/registry.service.d.ts.map +0 -1
|
@@ -1,6 +1,62 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { V as validateWithSchema, m as getTarget, l as getPossibleTarget, c as LOG_PERSIST_LOADER_KEY, k as generateResponse, R as updateTargetDetails, g as createLogger, h as createTarget, q as isCreateTargetAlreadyExistsError, J as scanTargetList, B as BaseValidator, a as CategoryList, i as deleteTarget, s as isOptimisticLockError, n as getTargetList, f as OPTIMISTIC_LOCK_FAILED_MESSAGE, O as OPTIMISTIC_LOCK_ERROR_CODE, w as logManager } from './list.api-BzbTJBsM.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
+
var CategoryConfig;
|
|
5
|
+
(function (CategoryConfig) {
|
|
6
|
+
CategoryConfig["CONFIG"] = "config";
|
|
7
|
+
})(CategoryConfig || (CategoryConfig = {}));
|
|
8
|
+
|
|
9
|
+
const targetIdSchema$2 = z.string().trim().min(1);
|
|
10
|
+
const getConfigSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
id: targetIdSchema$2.optional(),
|
|
13
|
+
value: z.string().trim().min(1).optional(),
|
|
14
|
+
})
|
|
15
|
+
.refine((payload) => {
|
|
16
|
+
const hasId = payload.id != null && payload.id !== "";
|
|
17
|
+
const hasValue = payload.value != null && payload.value !== "";
|
|
18
|
+
return hasId !== hasValue;
|
|
19
|
+
}, { message: "Provide exactly one of id or value" });
|
|
20
|
+
const configCategoryFilter$1 = {
|
|
21
|
+
field: "category",
|
|
22
|
+
operator: "eq",
|
|
23
|
+
value: CategoryConfig.CONFIG,
|
|
24
|
+
};
|
|
25
|
+
function buildConfigLookupFilters(payload) {
|
|
26
|
+
const filters = [configCategoryFilter$1];
|
|
27
|
+
if (payload.id == null || payload.id === "") {
|
|
28
|
+
filters.push({ field: "value", operator: "eq", value: payload.value });
|
|
29
|
+
}
|
|
30
|
+
return filters;
|
|
31
|
+
}
|
|
32
|
+
/** Fetch a Config by id or by {@link Config.value} key (`category=config`). */
|
|
33
|
+
const getConfig = validateWithSchema(getConfigSchema, "getConfigSchema")(async (payload) => {
|
|
34
|
+
const filterList = buildConfigLookupFilters(payload);
|
|
35
|
+
if (payload.id != null && payload.id !== "") {
|
|
36
|
+
const result = await getTarget({
|
|
37
|
+
id: payload.id,
|
|
38
|
+
filterList,
|
|
39
|
+
});
|
|
40
|
+
return {
|
|
41
|
+
...result,
|
|
42
|
+
data: result.data,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const result = await getPossibleTarget({
|
|
46
|
+
filterList,
|
|
47
|
+
});
|
|
48
|
+
if (result.data == null) {
|
|
49
|
+
return {
|
|
50
|
+
...result,
|
|
51
|
+
data: undefined,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
...result,
|
|
56
|
+
data: result.data,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
4
60
|
/**
|
|
5
61
|
* Read side of the log-persist pipeline: decode persisted `LogBatch` Lists into
|
|
6
62
|
* structured batches and flat entries. Pure and defensive — malformed rows are
|
|
@@ -124,12 +180,12 @@ var CategoryExtraction;
|
|
|
124
180
|
CategoryExtraction["EXTRACTION"] = "extraction";
|
|
125
181
|
})(CategoryExtraction || (CategoryExtraction = {}));
|
|
126
182
|
|
|
127
|
-
const targetIdSchema$
|
|
183
|
+
const targetIdSchema$1 = z.string().trim().min(1);
|
|
128
184
|
const loaderKeySchema = z.string().trim().min(1);
|
|
129
185
|
const postExtractionSchema = z.object({
|
|
130
186
|
name: z.string().trim().min(1),
|
|
131
187
|
/** Source Target id — for log analysis this is the producing Task id. */
|
|
132
|
-
sourceId: targetIdSchema$
|
|
188
|
+
sourceId: targetIdSchema$1,
|
|
133
189
|
loaderKey: loaderKeySchema,
|
|
134
190
|
meta: z.unknown().optional(),
|
|
135
191
|
objects: z.array(z.unknown()).min(1),
|
|
@@ -138,8 +194,8 @@ const postExtractionSchema = z.object({
|
|
|
138
194
|
});
|
|
139
195
|
const getExtractionSchema = z
|
|
140
196
|
.object({
|
|
141
|
-
id: targetIdSchema$
|
|
142
|
-
sourceId: targetIdSchema$
|
|
197
|
+
id: targetIdSchema$1.optional(),
|
|
198
|
+
sourceId: targetIdSchema$1.optional(),
|
|
143
199
|
loaderKey: loaderKeySchema.optional(),
|
|
144
200
|
})
|
|
145
201
|
.refine((payload) => {
|
|
@@ -152,12 +208,12 @@ const getExtractionSchema = z
|
|
|
152
208
|
}, { message: "Provide id, or both sourceId and loaderKey" });
|
|
153
209
|
const scanExtractionListSchema = z.object({
|
|
154
210
|
loaderKey: loaderKeySchema.optional(),
|
|
155
|
-
sourceId: targetIdSchema$
|
|
211
|
+
sourceId: targetIdSchema$1.optional(),
|
|
156
212
|
maxRows: z.number().int().min(1).max(500).optional(),
|
|
157
213
|
ascending: z.boolean().optional(),
|
|
158
214
|
});
|
|
159
215
|
const patchExtractionObjectsSchema = z.object({
|
|
160
|
-
id: targetIdSchema$
|
|
216
|
+
id: targetIdSchema$1,
|
|
161
217
|
objects: z.array(z.unknown()).min(1),
|
|
162
218
|
meta: z.unknown().optional(),
|
|
163
219
|
expectedRevision: z.number().int().min(0).optional(),
|
|
@@ -1241,45 +1297,33 @@ var ServiceLifecycleStatus;
|
|
|
1241
1297
|
ServiceLifecycleStatus["SUNSET"] = "SUNSET";
|
|
1242
1298
|
})(ServiceLifecycleStatus || (ServiceLifecycleStatus = {}));
|
|
1243
1299
|
|
|
1244
|
-
var CategoryConfig;
|
|
1245
|
-
(function (CategoryConfig) {
|
|
1246
|
-
CategoryConfig["CONFIG"] = "config";
|
|
1247
|
-
})(CategoryConfig || (CategoryConfig = {}));
|
|
1248
1300
|
/** Globally unique Config key for the declarative system service registry. */
|
|
1249
1301
|
const TARGET_SYSTEM_REGISTRY_KEY = "target-system-registry";
|
|
1302
|
+
/**
|
|
1303
|
+
* Default one EMPTY slot per known L3 service.
|
|
1304
|
+
* Override via `postSystemRegistryConfig` / `resetSystemRegistryConfig` payload or gc-service seed file.
|
|
1305
|
+
* Replica count = how many times the same `serviceValue` appears (not a separate maxInstances field).
|
|
1306
|
+
*/
|
|
1307
|
+
const DEFAULT_SYSTEM_REGISTRY_SEED_SLOTS = [
|
|
1308
|
+
{ serviceValue: "log-service" },
|
|
1309
|
+
{ serviceValue: "watch-service" },
|
|
1310
|
+
{ serviceValue: "download-service" },
|
|
1311
|
+
{ serviceValue: "storage-service" },
|
|
1312
|
+
{ serviceValue: "gc-service" },
|
|
1313
|
+
{ serviceValue: "upload-service" },
|
|
1314
|
+
{ serviceValue: "cv-service" },
|
|
1315
|
+
];
|
|
1250
1316
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1317
|
+
/**
|
|
1318
|
+
* Capacity slots on the system registry Config (`details.objects`).
|
|
1319
|
+
* Not fields on a Service Target row — see {@link Service} in `service.interface.ts`.
|
|
1320
|
+
*/
|
|
1255
1321
|
var ServiceSlotStatus;
|
|
1256
1322
|
(function (ServiceSlotStatus) {
|
|
1257
1323
|
ServiceSlotStatus["EMPTY"] = "EMPTY";
|
|
1258
1324
|
ServiceSlotStatus["ACTIVE"] = "ACTIVE";
|
|
1259
1325
|
})(ServiceSlotStatus || (ServiceSlotStatus = {}));
|
|
1260
|
-
var CategoryApi;
|
|
1261
|
-
(function (CategoryApi) {
|
|
1262
|
-
CategoryApi["API"] = "api";
|
|
1263
|
-
})(CategoryApi || (CategoryApi = {}));
|
|
1264
|
-
var ApiMethod;
|
|
1265
|
-
(function (ApiMethod) {
|
|
1266
|
-
ApiMethod["POST"] = "POST";
|
|
1267
|
-
ApiMethod["GET"] = "GET";
|
|
1268
|
-
ApiMethod["PUT"] = "PUT";
|
|
1269
|
-
ApiMethod["DELETE"] = "DELETE";
|
|
1270
|
-
})(ApiMethod || (ApiMethod = {}));
|
|
1271
1326
|
|
|
1272
|
-
const targetIdSchema$1 = z.string().trim().min(1);
|
|
1273
|
-
const getConfigSchema = z
|
|
1274
|
-
.object({
|
|
1275
|
-
id: targetIdSchema$1.optional(),
|
|
1276
|
-
value: z.string().trim().min(1).optional(),
|
|
1277
|
-
})
|
|
1278
|
-
.refine((payload) => {
|
|
1279
|
-
const hasId = payload.id != null && payload.id !== "";
|
|
1280
|
-
const hasValue = payload.value != null && payload.value !== "";
|
|
1281
|
-
return hasId !== hasValue;
|
|
1282
|
-
}, { message: "Provide exactly one of id or value" });
|
|
1283
1327
|
/** One declarative EMPTY slot entry for seeding the system registry. */
|
|
1284
1328
|
const systemRegistrySeedSlotSchema = z.object({
|
|
1285
1329
|
serviceValue: z.string().trim().min(1),
|
|
@@ -1293,28 +1337,11 @@ const postSystemRegistryConfigSchema = z.object({
|
|
|
1293
1337
|
const resetSystemRegistryConfigSchema = postSystemRegistryConfigSchema;
|
|
1294
1338
|
const DEFAULT_RESET_RETRY_ATTEMPTS = 5;
|
|
1295
1339
|
const RESET_RETRY_DELAY_MS = 50;
|
|
1296
|
-
/** Default one EMPTY slot per known L3 service (override via payload or seed file). */
|
|
1297
|
-
const DEFAULT_SYSTEM_REGISTRY_SEED_SLOTS = [
|
|
1298
|
-
{ serviceValue: "log-service" },
|
|
1299
|
-
{ serviceValue: "watch-service" },
|
|
1300
|
-
{ serviceValue: "download-service" },
|
|
1301
|
-
{ serviceValue: "storage-service" },
|
|
1302
|
-
{ serviceValue: "gc-service" },
|
|
1303
|
-
{ serviceValue: "upload-service" },
|
|
1304
|
-
{ serviceValue: "cv-service" },
|
|
1305
|
-
];
|
|
1306
1340
|
const configCategoryFilter = {
|
|
1307
1341
|
field: "category",
|
|
1308
1342
|
operator: "eq",
|
|
1309
1343
|
value: CategoryConfig.CONFIG,
|
|
1310
1344
|
};
|
|
1311
|
-
function buildConfigLookupFilters(payload) {
|
|
1312
|
-
const filters = [configCategoryFilter];
|
|
1313
|
-
if (payload.id == null || payload.id === "") {
|
|
1314
|
-
filters.push({ field: "value", operator: "eq", value: payload.value });
|
|
1315
|
-
}
|
|
1316
|
-
return filters;
|
|
1317
|
-
}
|
|
1318
1345
|
/** Build EMPTY {@link ServiceSlot} rows from seed entries (one slot per array item). */
|
|
1319
1346
|
function buildEmptyServiceSlots(seedSlots) {
|
|
1320
1347
|
return seedSlots.map(({ serviceValue }) => ({
|
|
@@ -1343,33 +1370,6 @@ function buildSystemRegistryConfigDetails(slots) {
|
|
|
1343
1370
|
objects: [...slots],
|
|
1344
1371
|
};
|
|
1345
1372
|
}
|
|
1346
|
-
/** Fetch a Config by id or by {@link Config.value} key (`category=config`). */
|
|
1347
|
-
const getConfig = validateWithSchema(getConfigSchema, "getConfigSchema")(async (payload) => {
|
|
1348
|
-
const filterList = buildConfigLookupFilters(payload);
|
|
1349
|
-
if (payload.id != null && payload.id !== "") {
|
|
1350
|
-
const result = await getTarget({
|
|
1351
|
-
id: payload.id,
|
|
1352
|
-
filterList,
|
|
1353
|
-
});
|
|
1354
|
-
return {
|
|
1355
|
-
...result,
|
|
1356
|
-
data: result.data,
|
|
1357
|
-
};
|
|
1358
|
-
}
|
|
1359
|
-
const result = await getPossibleTarget({
|
|
1360
|
-
filterList,
|
|
1361
|
-
});
|
|
1362
|
-
if (result.data == null) {
|
|
1363
|
-
return {
|
|
1364
|
-
...result,
|
|
1365
|
-
data: undefined,
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
|
-
return {
|
|
1369
|
-
...result,
|
|
1370
|
-
data: result.data,
|
|
1371
|
-
};
|
|
1372
|
-
});
|
|
1373
1373
|
/**
|
|
1374
1374
|
* Insert the globally unique system registry Config (`category=config`,
|
|
1375
1375
|
* `value=target-system-registry`). Rejects duplicates via `checkRedundancyFilterList`.
|
|
@@ -1435,6 +1435,22 @@ const resetSystemRegistryConfig = validateWithSchema(resetSystemRegistryConfigSc
|
|
|
1435
1435
|
throw new Error("[resetSystemRegistryConfig] Optimistic lock retries exhausted");
|
|
1436
1436
|
});
|
|
1437
1437
|
|
|
1438
|
+
var CategoryService;
|
|
1439
|
+
(function (CategoryService) {
|
|
1440
|
+
CategoryService["SERVICE"] = "service";
|
|
1441
|
+
})(CategoryService || (CategoryService = {}));
|
|
1442
|
+
var CategoryApi;
|
|
1443
|
+
(function (CategoryApi) {
|
|
1444
|
+
CategoryApi["API"] = "api";
|
|
1445
|
+
})(CategoryApi || (CategoryApi = {}));
|
|
1446
|
+
var ApiMethod;
|
|
1447
|
+
(function (ApiMethod) {
|
|
1448
|
+
ApiMethod["POST"] = "POST";
|
|
1449
|
+
ApiMethod["GET"] = "GET";
|
|
1450
|
+
ApiMethod["PUT"] = "PUT";
|
|
1451
|
+
ApiMethod["DELETE"] = "DELETE";
|
|
1452
|
+
})(ApiMethod || (ApiMethod = {}));
|
|
1453
|
+
|
|
1438
1454
|
const targetIdSchema = z.string().trim().min(1);
|
|
1439
1455
|
const enumMemberSchema = z.object({
|
|
1440
1456
|
key: z.string().trim().min(1),
|
|
@@ -2082,84 +2098,82 @@ async function releaseSystemRegistrySlotsByServiceId(input) {
|
|
|
2082
2098
|
throw new ServiceRegistryError("[releaseSystemRegistrySlotsByServiceId] Optimistic lock retries exhausted", "REGISTRY_UPDATE_FAILED");
|
|
2083
2099
|
}
|
|
2084
2100
|
/**
|
|
2085
|
-
* Append EMPTY {@link ServiceSlot} rows for
|
|
2086
|
-
*
|
|
2101
|
+
* Append one or more EMPTY {@link ServiceSlot} rows for a given `serviceValue`.
|
|
2102
|
+
*
|
|
2103
|
+
* Always grows capacity (does not skip when the key is already declared).
|
|
2104
|
+
* Use for replica scale-out (e.g. second `download-service` instance).
|
|
2087
2105
|
* Does not modify existing slots or release ACTIVE bindings.
|
|
2088
2106
|
*/
|
|
2089
|
-
async function
|
|
2090
|
-
const
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2107
|
+
async function appendSystemRegistryEmptySlots(input) {
|
|
2108
|
+
const serviceValue = input.serviceValue.trim();
|
|
2109
|
+
if (serviceValue === "") {
|
|
2110
|
+
throw new Error("[appendSystemRegistryEmptySlots] serviceValue must not be empty");
|
|
2111
|
+
}
|
|
2112
|
+
const count = input.count ?? 1;
|
|
2113
|
+
if (!Number.isInteger(count) || count < 1) {
|
|
2114
|
+
throw new Error("[appendSystemRegistryEmptySlots] count must be an integer >= 1");
|
|
2095
2115
|
}
|
|
2096
2116
|
const maxAttempts = input.maxAttempts ?? DEFAULT_REGISTER_RETRY_ATTEMPTS;
|
|
2097
2117
|
const logger = createLogger({
|
|
2098
|
-
module: "
|
|
2118
|
+
module: "appendSystemRegistryEmptySlots",
|
|
2099
2119
|
traceId: input.traceId,
|
|
2100
|
-
labels: {
|
|
2120
|
+
labels: { serviceValue, count: String(count) },
|
|
2101
2121
|
});
|
|
2102
|
-
logger.info("开始追加 registry
|
|
2122
|
+
logger.info("开始追加 EMPTY registry 槽位", {
|
|
2103
2123
|
topic: LOG_TOPIC_REGISTRY,
|
|
2104
|
-
data: {
|
|
2124
|
+
data: { serviceValue, count },
|
|
2105
2125
|
});
|
|
2106
2126
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
2107
2127
|
try {
|
|
2108
2128
|
const config = await loadSystemRegistryConfig();
|
|
2109
2129
|
const revision = parseRegistryRevision(config.details.meta);
|
|
2110
2130
|
const slots = parseServiceSlots(config);
|
|
2111
|
-
const
|
|
2112
|
-
const
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
if (isServiceValueDeclared(nextSlots, serviceValue)) {
|
|
2116
|
-
skipped.push(serviceValue);
|
|
2117
|
-
continue;
|
|
2118
|
-
}
|
|
2119
|
-
nextSlots.push({
|
|
2131
|
+
const capacityBefore = slots.filter((slot) => slot.serviceValue === serviceValue).length;
|
|
2132
|
+
const nextSlots = [
|
|
2133
|
+
...slots,
|
|
2134
|
+
...Array.from({ length: count }, () => ({
|
|
2120
2135
|
serviceValue,
|
|
2121
2136
|
serviceId: null,
|
|
2122
2137
|
status: ServiceSlotStatus.EMPTY,
|
|
2123
|
-
})
|
|
2124
|
-
|
|
2125
|
-
}
|
|
2126
|
-
if (added.length === 0) {
|
|
2127
|
-
logger.info("所有 service 已声明 — 无需追加", {
|
|
2128
|
-
topic: LOG_TOPIC_REGISTRY,
|
|
2129
|
-
data: { serviceValues, skipped },
|
|
2130
|
-
});
|
|
2131
|
-
return { config, added, skipped: serviceValues };
|
|
2132
|
-
}
|
|
2138
|
+
})),
|
|
2139
|
+
];
|
|
2133
2140
|
await persistSlotClaim({
|
|
2134
2141
|
configId: config.id,
|
|
2135
2142
|
revision,
|
|
2136
2143
|
slots: nextSlots,
|
|
2137
2144
|
});
|
|
2138
2145
|
const updated = await loadSystemRegistryConfig();
|
|
2139
|
-
|
|
2146
|
+
const capacityAfter = parseServiceSlots(updated).filter((slot) => slot.serviceValue === serviceValue).length;
|
|
2147
|
+
logger.info("EMPTY registry 槽位追加成功", {
|
|
2140
2148
|
topic: LOG_TOPIC_REGISTRY,
|
|
2141
|
-
data: {
|
|
2149
|
+
data: { serviceValue, appended: count, capacityBefore, capacityAfter, attempt },
|
|
2142
2150
|
});
|
|
2143
|
-
return {
|
|
2151
|
+
return {
|
|
2152
|
+
config: updated,
|
|
2153
|
+
serviceValue,
|
|
2154
|
+
appended: count,
|
|
2155
|
+
capacityBefore,
|
|
2156
|
+
capacityAfter,
|
|
2157
|
+
};
|
|
2144
2158
|
}
|
|
2145
2159
|
catch (error) {
|
|
2146
2160
|
if (isOptimisticLockError(error) && attempt < maxAttempts) {
|
|
2147
2161
|
logger.warn("registry 乐观锁冲突,重试", {
|
|
2148
2162
|
topic: LOG_TOPIC_REGISTRY,
|
|
2149
|
-
data: {
|
|
2163
|
+
data: { serviceValue, count, attempt, maxAttempts },
|
|
2150
2164
|
});
|
|
2151
2165
|
await sleep$1(50 * attempt);
|
|
2152
2166
|
continue;
|
|
2153
2167
|
}
|
|
2154
2168
|
const message = error instanceof Error ? error.message : String(error);
|
|
2155
|
-
logger.error("registry 槽位追加失败", {
|
|
2169
|
+
logger.error("EMPTY registry 槽位追加失败", {
|
|
2156
2170
|
topic: LOG_TOPIC_REGISTRY,
|
|
2157
|
-
data: {
|
|
2171
|
+
data: { serviceValue, count, attempt, message },
|
|
2158
2172
|
});
|
|
2159
2173
|
throw new ServiceRegistryError(message, "REGISTRY_UPDATE_FAILED");
|
|
2160
2174
|
}
|
|
2161
2175
|
}
|
|
2162
|
-
throw new ServiceRegistryError("[
|
|
2176
|
+
throw new ServiceRegistryError("[appendSystemRegistryEmptySlots] Optimistic lock retries exhausted", "REGISTRY_UPDATE_FAILED");
|
|
2163
2177
|
}
|
|
2164
2178
|
/**
|
|
2165
2179
|
* Claim one EMPTY slot for a running Service instance (`EMPTY → ACTIVE` only).
|
|
@@ -2739,6 +2753,166 @@ async function fetchBinaryWithRetry(url, init, options) {
|
|
|
2739
2753
|
return response.arrayBuffer();
|
|
2740
2754
|
}
|
|
2741
2755
|
|
|
2756
|
+
/**
|
|
2757
|
+
* Media Link protocol — Link rows with value/loaderKey in {@link MEDIA_VALUES}.
|
|
2758
|
+
* No separate Target category; category remains `link`.
|
|
2759
|
+
*/
|
|
2760
|
+
/** Fixed digest algorithm for single-file media `contentHash`. */
|
|
2761
|
+
const MEDIA_CONTENT_HASH_ALGORITHM = "sha256";
|
|
2762
|
+
/** Hex prefix length for {@link buildMediaNameFromLocator}. */
|
|
2763
|
+
const MEDIA_CONTENT_HASH_PREFIX_LENGTH = 6;
|
|
2764
|
+
const MEDIA_VALUES = ["video", "audio", "image", "image-list"];
|
|
2765
|
+
function isMediaValue(value) {
|
|
2766
|
+
return MEDIA_VALUES.includes(value);
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
/**
|
|
2770
|
+
* Assemble a media {@link Link} draft (`category=link`, `loaderKey === value`).
|
|
2771
|
+
* Does not validate filesystem or write to Supabase.
|
|
2772
|
+
*/
|
|
2773
|
+
function buildMediaLinkDraft(input) {
|
|
2774
|
+
if (!isMediaValue(input.value)) {
|
|
2775
|
+
throw new Error(`buildMediaLinkDraft: unsupported media value: ${String(input.value)}`);
|
|
2776
|
+
}
|
|
2777
|
+
const name = input.name.trim();
|
|
2778
|
+
if (name === "") {
|
|
2779
|
+
throw new Error("buildMediaLinkDraft: name is empty");
|
|
2780
|
+
}
|
|
2781
|
+
const storageProvider = input.storageProvider.trim();
|
|
2782
|
+
if (storageProvider === "") {
|
|
2783
|
+
throw new Error("buildMediaLinkDraft: storageProvider is empty");
|
|
2784
|
+
}
|
|
2785
|
+
const locator = input.locator.trim();
|
|
2786
|
+
if (locator === "") {
|
|
2787
|
+
throw new Error("buildMediaLinkDraft: locator is empty");
|
|
2788
|
+
}
|
|
2789
|
+
if (!Number.isFinite(input.size) || input.size < 0) {
|
|
2790
|
+
throw new Error("buildMediaLinkDraft: size must be a non-negative number");
|
|
2791
|
+
}
|
|
2792
|
+
const isList = input.value === "image-list";
|
|
2793
|
+
const contentHash = isList ? "" : input.contentHash.trim().toLowerCase();
|
|
2794
|
+
const mimeType = isList ? "" : input.mimeType.trim();
|
|
2795
|
+
if (!isList && contentHash === "") {
|
|
2796
|
+
throw new Error("buildMediaLinkDraft: contentHash is required for single-file media");
|
|
2797
|
+
}
|
|
2798
|
+
if (!isList && mimeType === "") {
|
|
2799
|
+
throw new Error("buildMediaLinkDraft: mimeType is required for single-file media");
|
|
2800
|
+
}
|
|
2801
|
+
const original = {
|
|
2802
|
+
storageProvider,
|
|
2803
|
+
locator,
|
|
2804
|
+
contentHash,
|
|
2805
|
+
size: Math.floor(input.size),
|
|
2806
|
+
mimeType,
|
|
2807
|
+
};
|
|
2808
|
+
return buildLinkTargetDraft({
|
|
2809
|
+
name,
|
|
2810
|
+
value: input.value,
|
|
2811
|
+
description: input.description ?? "",
|
|
2812
|
+
preview: "",
|
|
2813
|
+
loaderKey: input.value,
|
|
2814
|
+
tagList: input.tagList ?? [],
|
|
2815
|
+
original,
|
|
2816
|
+
});
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
const VIDEO_EXT_MIME = {
|
|
2820
|
+
mp4: "video/mp4",
|
|
2821
|
+
m4v: "video/mp4",
|
|
2822
|
+
mov: "video/quicktime",
|
|
2823
|
+
mkv: "video/x-matroska",
|
|
2824
|
+
webm: "video/webm",
|
|
2825
|
+
avi: "video/x-msvideo",
|
|
2826
|
+
mpeg: "video/mpeg",
|
|
2827
|
+
mpg: "video/mpeg",
|
|
2828
|
+
wmv: "video/x-ms-wmv",
|
|
2829
|
+
flv: "video/x-flv",
|
|
2830
|
+
ts: "video/mp2t",
|
|
2831
|
+
m2ts: "video/mp2t",
|
|
2832
|
+
};
|
|
2833
|
+
const AUDIO_EXT_MIME = {
|
|
2834
|
+
wav: "audio/wav",
|
|
2835
|
+
mp3: "audio/mpeg",
|
|
2836
|
+
m4a: "audio/mp4",
|
|
2837
|
+
aac: "audio/aac",
|
|
2838
|
+
flac: "audio/flac",
|
|
2839
|
+
ogg: "audio/ogg",
|
|
2840
|
+
oga: "audio/ogg",
|
|
2841
|
+
opus: "audio/opus",
|
|
2842
|
+
wma: "audio/x-ms-wma",
|
|
2843
|
+
};
|
|
2844
|
+
const IMAGE_EXT_MIME = {
|
|
2845
|
+
jpg: "image/jpeg",
|
|
2846
|
+
jpeg: "image/jpeg",
|
|
2847
|
+
png: "image/png",
|
|
2848
|
+
webp: "image/webp",
|
|
2849
|
+
gif: "image/gif",
|
|
2850
|
+
bmp: "image/bmp",
|
|
2851
|
+
tif: "image/tiff",
|
|
2852
|
+
tiff: "image/tiff",
|
|
2853
|
+
};
|
|
2854
|
+
function extensionOf(pathOrUrl) {
|
|
2855
|
+
const cleaned = pathOrUrl.split(/[?#]/)[0] ?? pathOrUrl;
|
|
2856
|
+
const base = cleaned.replace(/\\/g, "/").split("/").pop() ?? cleaned;
|
|
2857
|
+
const dot = base.lastIndexOf(".");
|
|
2858
|
+
if (dot <= 0 || dot === base.length - 1) {
|
|
2859
|
+
return "";
|
|
2860
|
+
}
|
|
2861
|
+
return base.slice(dot + 1).toLowerCase();
|
|
2862
|
+
}
|
|
2863
|
+
/** Guess MIME from path extension; `null` when unknown. */
|
|
2864
|
+
function guessMediaMime(locator, value) {
|
|
2865
|
+
const ext = extensionOf(locator);
|
|
2866
|
+
if (ext === "") {
|
|
2867
|
+
return null;
|
|
2868
|
+
}
|
|
2869
|
+
if (value === "video") {
|
|
2870
|
+
return VIDEO_EXT_MIME[ext] ?? null;
|
|
2871
|
+
}
|
|
2872
|
+
if (value === "audio") {
|
|
2873
|
+
return AUDIO_EXT_MIME[ext] ?? null;
|
|
2874
|
+
}
|
|
2875
|
+
return IMAGE_EXT_MIME[ext] ?? null;
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
/**
|
|
2879
|
+
* `{basename}.{hash6}.{ext}` from an absolute (or path-like) locator and full content hash.
|
|
2880
|
+
* Does not touch the filesystem.
|
|
2881
|
+
*/
|
|
2882
|
+
function buildMediaNameFromLocator(locator, contentHash) {
|
|
2883
|
+
const trimmedLocator = locator.trim();
|
|
2884
|
+
if (trimmedLocator === "") {
|
|
2885
|
+
throw new Error("buildMediaNameFromLocator: locator is empty");
|
|
2886
|
+
}
|
|
2887
|
+
const hash = contentHash.trim().toLowerCase();
|
|
2888
|
+
if (hash.length < MEDIA_CONTENT_HASH_PREFIX_LENGTH) {
|
|
2889
|
+
throw new Error(`buildMediaNameFromLocator: contentHash must be at least ${MEDIA_CONTENT_HASH_PREFIX_LENGTH} hex chars`);
|
|
2890
|
+
}
|
|
2891
|
+
const hash6 = hash.slice(0, MEDIA_CONTENT_HASH_PREFIX_LENGTH);
|
|
2892
|
+
const normalized = trimmedLocator.replace(/\\/g, "/");
|
|
2893
|
+
const base = normalized.split("/").pop() ?? normalized;
|
|
2894
|
+
if (base === "" || base === "." || base === "..") {
|
|
2895
|
+
throw new Error(`buildMediaNameFromLocator: invalid basename from locator: ${locator}`);
|
|
2896
|
+
}
|
|
2897
|
+
const dot = base.lastIndexOf(".");
|
|
2898
|
+
if (dot <= 0 || dot === base.length - 1) {
|
|
2899
|
+
return `${base}.${hash6}`;
|
|
2900
|
+
}
|
|
2901
|
+
const stem = base.slice(0, dot);
|
|
2902
|
+
const ext = base.slice(dot + 1);
|
|
2903
|
+
return `${stem}.${hash6}.${ext}`;
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
/** Dedup key: `category=link` + `value` + `name` (matches register / find). */
|
|
2907
|
+
function mediaLinkDedupFilters(input) {
|
|
2908
|
+
const name = input.name.trim();
|
|
2909
|
+
return [
|
|
2910
|
+
{ field: "category", operator: "eq", value: CategoryLink.LINK },
|
|
2911
|
+
{ field: "value", operator: "eq", value: input.value },
|
|
2912
|
+
{ field: "name", operator: "eq", value: name },
|
|
2913
|
+
];
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2742
2916
|
/** Read a dotted path (e.g. `data.items`) from a parsed JSON value. */
|
|
2743
2917
|
function getValueAtPath(value, path) {
|
|
2744
2918
|
if (path == null || path.trim() === "") {
|
|
@@ -3313,5 +3487,5 @@ function summarizeTaskQueue(tasks, taskType, statuses) {
|
|
|
3313
3487
|
return tasks.filter((task) => task.value === taskType && statuses.includes(task.details.status)).length;
|
|
3314
3488
|
}
|
|
3315
3489
|
|
|
3316
|
-
export {
|
|
3317
|
-
//# sourceMappingURL=task-queue-
|
|
3490
|
+
export { fetchWithRetry as $, ApiMethod as A, buildSystemRegistryConfigDetails as B, CategoryConfig as C, DEFAULT_SYSTEM_REGISTRY_SEED_SLOTS as D, EMPTY_REGISTRY_SLOT_RUNTIME_STATE as E, claimServiceRegistrySlot as F, classifyNetworkError as G, countTasksByType as H, createActiveServiceLifecycle as I, createClaimedRegistrySlotRuntimeState as J, createStorageProviderRegistry as K, LINK_MANIFEST_VERSION as L, MEDIA_CONTENT_HASH_ALGORITHM as M, NodeStatus as N, createUploadTracker as O, POST_TASK_DEFAULT_MAX_ATTEMPTS as P, decodeLogBatch as Q, ResultCode as R, ServiceLifecycleStatus as S, TARGET_SYSTEM_REGISTRY_KEY as T, decodeLogBatchList as U, defaultL3ServiceDetails as V, deleteParcel as W, deleteParcelSchema as X, escapeIlikePattern as Y, evaluateBusyNodeLiveness as Z, fetchBinaryWithRetry as _, CategoryExtraction as a, postTask as a$, fieldDefinitionSchema as a0, flattenLogBatch as a1, flattenLogBatches as a2, formatNetworkError as a3, getApi as a4, getApiSchema as a5, getConfig as a6, getConfigSchema as a7, getExtraction as a8, getExtractionSchema as a9, patchChangeTaskStatus as aA, patchChangeTaskStatusSchema as aB, patchClaimTask as aC, patchClaimTaskSchema as aD, patchExtractionObjects as aE, patchExtractionObjectsSchema as aF, patchNodeHeartBeat as aG, patchNodeHeartBeatSchema as aH, patchServiceRuntime as aI, patchStopNode as aJ, patchStopNodeSchema as aK, patchTaskProgress as aL, patchTaskProgressSchema as aM, postApi as aN, postApiSchema as aO, postExtraction as aP, postExtractionSchema as aQ, postLinkCreate as aR, postParcel as aS, postParcelSchema as aT, postRegisterNode as aU, postRegisterNodeSchema as aV, postService as aW, postServiceInstance as aX, postServiceSchema as aY, postSystemRegistryConfig as aZ, postSystemRegistryConfigSchema as a_, getParcel as aa, getParcelSchema as ab, getScanRemoteRepoValues as ac, getScanRemoteRepoValuesSchema as ad, getService as ae, getServiceSchema as af, getTargetSystemRegistry as ag, getValueAtPath as ah, guessMediaMime as ai, installChunkFetchRegistry as aj, isHttpUrl as ak, isLocalFilesystemPath as al, isLogBatchList as am, isLogEntry as an, isMediaValue as ao, isOpaqueChunkUrl as ap, isRetryableHttpStatus as aq, linkTargetDraftBuildInputSchema as ar, mediaLinkDedupFilters as as, parcelDetailsSchema as at, parseLogBatchMeta as au, parseProviderPrefixedUrl as av, parseServiceSlot as aw, parseServiceSlots as ax, patchChangeNodeStatus as ay, patchChangeNodeStatusSchema as az, CategoryLink as b, postTaskSchema as b0, postTaskWithRetry as b1, publishParcel as b2, registerProviderChunkResolver as b3, registerService as b4, registerServiceAtStartup as b5, registrySlotRuntimePatchFromGuardResult as b6, releaseSystemRegistrySlots as b7, releaseSystemRegistrySlotsByServiceId as b8, requestHasBody as b9, toError as bA, createTaskRow as bB, resetSystemRegistryConfig as ba, resetSystemRegistryConfigSchema as bb, resolveActiveRegistryServiceId as bc, resolveFetchUrl as bd, restoreParcel as be, restoreParcelById as bf, runRegistrySlotGuardCheck as bg, sanitizeFileName as bh, sanitizeParcelFileName as bi, scanExtractionList as bj, scanExtractionListSchema as bk, schemaDefinitionSchema as bl, serviceDetailsSchema as bm, serviceLifecycleSchema as bn, serviceNodeSnapshotSchema as bo, serviceRuntimeSchema as bp, sha256Hex as bq, summarizeTaskQueue as br, systemRegistrySeedSlotSchema as bs, toPostgrestTextArrayLiteral as bt, unregisterService as bu, unregisterServiceAtShutdown as bv, getErrorMessage as bw, LOG_TOPIC_NODE as bx, LOG_TOPIC_TASK as by, CRITICAL_UNKNOWN_TASK_TRACE_ID as bz, CategoryNode as c, CategoryParcel as d, CategoryRepo as e, CategoryService as f, CategoryTask as g, LIST_MANIFEST_VERSION as h, MEDIA_CONTENT_HASH_PREFIX_LENGTH as i, MEDIA_VALUES as j, ParcelManager as k, PostLinkValidator as l, ServiceRegistryError as m, ServiceSlotStatus as n, TASK_REPO_USAGE as o, TaskStatus as p, TaskStatusAction as q, apiDetailsSchema as r, appendSystemRegistryEmptySlots as s, assertRegistrySlotAvailable as t, assertRegistrySlotOwner as u, buildEmptyServiceSlots as v, buildLinkTargetDraft as w, buildListTargetDraft as x, buildMediaLinkDraft as y, buildMediaNameFromLocator as z };
|
|
3491
|
+
//# sourceMappingURL=task-queue-DufG7PlX.js.map
|