mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
103 lines
5.4 KiB
Markdown
103 lines
5.4 KiB
Markdown
# Application construction
|
|
|
|
`gods-eye-view/application` exports `createApplication`. Importing it does not
|
|
create a viewer, discover configuration, start requests, or attach browser
|
|
listeners. Construction is also inactive until the caller invokes `start()`.
|
|
|
|
The caller supplies four constructors, in this order:
|
|
|
|
| Constructor | Receives | Standalone implementation |
|
|
| ---------------- | ---------------------------------------------- | --------------------------------------------- |
|
|
| `createScene` | `signal`, `defer` | Viewer, attribution and initial map |
|
|
| `createControls` | `scene`, `signal`, `defer` | Style manager and camera presentation |
|
|
| `createData` | `scene`, `controls`, `signal`, `defer` | Layer catalog, registration and restoration |
|
|
| `createTools` | `scene`, `controls`, `data`, `signal`, `defer` | Scenes, annotations, voice and page listeners |
|
|
|
|
Each constructor returns its component object, or a promise for that object.
|
|
Those objects are passed unchanged to later constructors. Configuration and
|
|
service instances belong in the caller's closures; the application does not
|
|
interpret provider names, environment variables, endpoints, or module paths.
|
|
There is no module discovery or automatic import mechanism.
|
|
|
|
```js
|
|
import { createApplication } from 'gods-eye-view/application';
|
|
import { createApplicationViewer } from 'gods-eye-view/application/viewer';
|
|
|
|
const app = createApplication({
|
|
createScene({ defer }) {
|
|
const viewer = createApplicationViewer({ container, creditContainer });
|
|
defer(() => viewer.destroy());
|
|
return { viewer };
|
|
},
|
|
createControls,
|
|
createData,
|
|
createTools,
|
|
});
|
|
const unsubscribe = app.subscribe(({ status, phase }) => {
|
|
// Update the caller's startup presentation.
|
|
});
|
|
await app.start();
|
|
// When the application is no longer needed:
|
|
unsubscribe();
|
|
await app.destroy();
|
|
```
|
|
|
|
The example's containers and three remaining constructors are supplied by the
|
|
consumer. The viewer helper preserves the standalone viewer's render settings;
|
|
it neither selects map sources nor reads keys. Supply a visible credit container
|
|
and retain all attribution required by the chosen sources. Cesium is external to
|
|
this export: the consuming build must provide the same instance used elsewhere
|
|
in its application.
|
|
|
|
## Lifecycle and ownership
|
|
|
|
Register `defer(cleanup)` immediately after acquiring each resource, before any
|
|
`await`. Cleanup registration remains open until that constructor settles. Each
|
|
callback may return a promise. Within a phase, callbacks run in reverse order.
|
|
Across phases, teardown runs **tools, controls, data, scene**: controls must cancel
|
|
restoration while their data manager and viewer are still alive.
|
|
|
|
`start()` returns the same promise on repeated calls. `destroy()` is terminal and
|
|
also returns the same promise on repeated calls. It aborts the shared signal
|
|
immediately, waits for an in-flight constructor to settle, and runs all registered
|
|
cleanup callbacks. Constructors must forward the signal to cancellable operations
|
|
and check it after awaits. If a provider cannot cancel construction, register
|
|
cleanup for its late result before returning. Destruction waits for that result;
|
|
it does not pretend a pending resource has already been released.
|
|
|
|
A constructor failure triggers the same cleanup before rejecting startup.
|
|
Cleanup failures do not stop the remaining callbacks; they are reported through
|
|
an `AggregateError`. Constructors own cleanup for resources created internally,
|
|
including anything allocated before their own construction throws.
|
|
|
|
`getState()` returns a frozen `{ status, phase }` snapshot. Status is `created`,
|
|
`starting`, `ready`, `destroying`, `destroyed`, or `failed`. `phase` identifies the
|
|
constructor during startup. `subscribe(listener)` immediately reports the current
|
|
snapshot and returns an unsubscribe function. Install observers before `start()`
|
|
to receive every startup phase. Observer failures cannot interrupt startup or
|
|
teardown. `getComponents()` returns a frozen, shallow snapshot of the currently
|
|
constructed component objects; the component instances themselves remain mutable.
|
|
|
|
`ready` means all constructors have returned. Background feed activity and the
|
|
standalone share-restoration result keep their existing separate contracts.
|
|
|
|
## Standalone wiring
|
|
|
|
`src/main.js` reads the existing browser configuration and starts
|
|
`src/editions/local/application.js`. That module selects the four implementations
|
|
in its directory. Scene setup, controls, layer registration, tools and loading
|
|
chrome have separate owners. The existing `window.__godsEyeView` debugging shape
|
|
is preserved while the app is running.
|
|
|
|
The standalone controls and layer modules still contain page-scoped state.
|
|
Only one standalone application may be constructed per page. Shutdown releases
|
|
its runtime resources and debugging handles; reload the page to start again.
|
|
It is not an embeddable, removable HTML shell or a multiple-viewer implementation.
|
|
Consumers of the small application export supply their own component ownership;
|
|
the lifecycle controller itself has no shared instance state.
|
|
|
|
Later component extractions can replace a constructor's internals without
|
|
changing the startup contract or moving standalone imports into the package.
|
|
Run the unit suite, package boundary gate, build, tracking and first-run browser
|
|
checks when changing this wiring.
|