mikser-io 9.2.1 → 9.3.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/package.json +1 -1
- package/src/plugins/api.js +31 -0
- package/src/runtime.js +17 -0
package/package.json
CHANGED
package/src/plugins/api.js
CHANGED
|
@@ -394,6 +394,37 @@ export function api(options = {}) {
|
|
|
394
394
|
// api.endpoints.admin { token: '...', operations: ['list','update','delete','render'] }
|
|
395
395
|
for (const [name, ep] of Object.entries(endpoints)) {
|
|
396
396
|
const router = express.Router()
|
|
397
|
+
|
|
398
|
+
// Nothing is served until the first build cycle has finished.
|
|
399
|
+
//
|
|
400
|
+
// The server binds at the end of the loaded phase — before
|
|
401
|
+
// process() has emitted an entity — so without this the endpoint
|
|
402
|
+
// spends the whole first build answering against an empty catalog.
|
|
403
|
+
// Renders fail outright (the layouts registry fills during
|
|
404
|
+
// process()), and reads are worse than that: a list returns
|
|
405
|
+
// whichever subset exists at that instant, which is a wrong answer
|
|
406
|
+
// wearing a 200. A consumer seeding its routes from that gets zero
|
|
407
|
+
// routes and renders blank pages.
|
|
408
|
+
//
|
|
409
|
+
// 503, not 4xx, and Retry-After: this is the one honest status
|
|
410
|
+
// here. It says the request was fine and the server was not, which
|
|
411
|
+
// is exactly the case, and it is the status every HTTP client
|
|
412
|
+
// already knows to retry. A 422 or a 500 invites the caller to
|
|
413
|
+
// treat a transient build as a permanent defect and give up.
|
|
414
|
+
//
|
|
415
|
+
// The window is normally sub-second and easy to miss. It stretches
|
|
416
|
+
// whenever the cache has to be rebuilt from scratch — most notably
|
|
417
|
+
// after an engine upgrade, where the schema stamp no longer matches
|
|
418
|
+
// and the catalog is wiped before the rebuild.
|
|
419
|
+
router.use((req, res, next) => {
|
|
420
|
+
if (runtime.ready) return next()
|
|
421
|
+
res.set('Retry-After', '1')
|
|
422
|
+
res.status(503).json({
|
|
423
|
+
error: 'Mikser is still building — the catalog is not ready yet',
|
|
424
|
+
ready: false,
|
|
425
|
+
})
|
|
426
|
+
})
|
|
427
|
+
|
|
397
428
|
router.use(express.json({ limit: ep.bodyLimit ?? globalBodyLimit }))
|
|
398
429
|
|
|
399
430
|
// Operations default to the safer shape when no token is set
|
package/src/runtime.js
CHANGED
|
@@ -12,6 +12,22 @@ const runtime = {
|
|
|
12
12
|
journal: [],
|
|
13
13
|
validators: [],
|
|
14
14
|
started: false,
|
|
15
|
+
// Whether the FIRST build cycle has finished — i.e. whether the catalog
|
|
16
|
+
// reflects the sources yet. Not the same question as `started`, which is
|
|
17
|
+
// true from the moment the loaded phase ends, before process() has emitted
|
|
18
|
+
// a single entity.
|
|
19
|
+
//
|
|
20
|
+
// Transports need this. The server binds at the end of the loaded phase, by
|
|
21
|
+
// design, so that every plugin has registered its routes first — which also
|
|
22
|
+
// means requests are accepted while the catalog is still empty. A render
|
|
23
|
+
// arriving then cannot resolve its layout (the layouts registry is filled
|
|
24
|
+
// during process()), and a list returns whatever subset happens to exist,
|
|
25
|
+
// which is worse: it is wrong without being an error.
|
|
26
|
+
//
|
|
27
|
+
// Set once and never cleared. Later cycles rebuild against a catalog that
|
|
28
|
+
// is already populated, so they are serveable; flapping this on every watch
|
|
29
|
+
// rebuild would take the endpoint down for every keystroke.
|
|
30
|
+
ready: false,
|
|
15
31
|
// Name of the lifecycle phase currently executing — null between
|
|
16
32
|
// phases. Set inside start() / process() / render() etc. before
|
|
17
33
|
// each callHooks(), cleared on completion. Read by mikser-io-mcp's
|
|
@@ -85,6 +101,7 @@ const runtime = {
|
|
|
85
101
|
|
|
86
102
|
this.started = true
|
|
87
103
|
await this.process()
|
|
104
|
+
this.ready = true
|
|
88
105
|
},
|
|
89
106
|
|
|
90
107
|
async process() {
|