|
| 1 | +--- |
| 2 | +'@objectstack/cli': patch |
| 3 | +'@objectstack/core': patch |
| 4 | +'@objectstack/metadata': patch |
| 5 | +'@objectstack/runtime': patch |
| 6 | +--- |
| 7 | + |
| 8 | +fix(cli,core,metadata,runtime): `os serve` boots with no compiled artifact — the platform does not need an application to start (#4085) |
| 9 | + |
| 10 | +The artifact (`dist/objectstack.json`) defines an **application**. ObjectStack is |
| 11 | +a development platform, so it has to start without one — but `os serve |
| 12 | +objectstack.config.ts` died during boot whenever the artifact was absent: |
| 13 | + |
| 14 | +``` |
| 15 | + Loading objectstack.config.ts... |
| 16 | +[StandaloneStack] artifact read FAILED: path='…/dist/objectstack.json' error=ENOENT… |
| 17 | +
|
| 18 | + ✗ Service 'manifest' is async - use await |
| 19 | +``` |
| 20 | + |
| 21 | +Exit 1 — on a **known-good app** (`examples/app-todo` fails the same way with |
| 22 | +only its `dist/objectstack.json` moved aside), and on every freshly authored |
| 23 | +project between `os init` and its first `os compile`. The message named neither |
| 24 | +the missing artifact nor a fix, so it read as an internal kernel fault. |
| 25 | + |
| 26 | +Three separate faults, each of which alone was enough to refuse the boot: |
| 27 | + |
| 28 | +- **`serve` registered the config-derived `AppPlugin` before the stack's own |
| 29 | + `plugins[]`.** Registration order *is* the kernel's init/start order, and that |
| 30 | + slot sits ahead of `ObjectQLPlugin` (which registers `manifest`/`objectql`) and |
| 31 | + `DefaultDatasourcePlugin` (which connects the database the app seeds through). |
| 32 | + The wrap is now **appended** to `plugins[]`, the same slot |
| 33 | + `createStandaloneStack` gives its artifact-derived `AppPlugin` — so config-boot |
| 34 | + and artifact-boot share one plugin order. The artifact path never hit this, |
| 35 | + which is exactly what made a plugin-**order** bug look artifact-related. |
| 36 | + |
| 37 | +- **`ctx.getService()` reported a never-registered service as "is async".** |
| 38 | + `PluginLoader.getService` is an `async` method, so its return value is *always* |
| 39 | + a Promise and its internal "not found" rejection can never surface |
| 40 | + synchronously — the kernel read the answer off that Promise and told every |
| 41 | + caller to `await` a service that did not exist, while the `not found` branch |
| 42 | + below it was unreachable. It now decides from the registry: absent ⇒ |
| 43 | + `[Kernel] Service 'x' not found`, registered-but-uninstantiated ⇒ the unchanged |
| 44 | + `Service 'x' is async - use await`. The same crash now reads |
| 45 | + `[Kernel] Service 'manifest' not found`, which points at the layer that is |
| 46 | + actually wrong. |
| 47 | + |
| 48 | +- **`MetadataPlugin` treated an absent `local-file` artifact as fatal.** |
| 49 | + `createStandaloneStack` always points it at `dist/objectstack.json`, so a stack |
| 50 | + with no app at all could not boot. A **missing** local artifact is now "nothing |
| 51 | + compiled yet": it logs, starts empty, and leaves the artifact watcher armed, so |
| 52 | + a later `os compile` hydrates the running server. The tolerance is |
| 53 | + ENOENT-only — a malformed or unreadable artifact stays fatal — and |
| 54 | + `bootstrap: 'artifact-only'` (sealed runtime, where the artifact *is* the |
| 55 | + deployment) keeps failing loudly rather than silently serving an empty runtime. |
| 56 | + |
| 57 | +`[StandaloneStack] artifact read FAILED … ENOENT` is likewise no longer shouted |
| 58 | +at callers for whom "no artifact" is a healthy state; a present-but-unusable |
| 59 | +artifact keeps the loud warning. |
| 60 | + |
| 61 | +Pinned by an e2e pair that drives the real `os serve` with **no `os compile` |
| 62 | +anywhere**: an app defined only by `objectstack.config.ts` (asserting its object |
| 63 | +is in the started plugin set, not merely that boot survived) and a bare |
| 64 | +`export default {}` platform. The #4012 fixture drops the `os compile` this bug |
| 65 | +had forced on it. |
0 commit comments