frontage 0.16.1__py3-none-win_amd64.whl
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.
- frontage/__init__.py +38 -0
- frontage/__init__.pyi +85 -0
- frontage/__main__.py +8 -0
- frontage/_bin/fpy.exe +0 -0
- frontage/_exports.py +87 -0
- frontage/_runtime/boot.js +127 -0
- frontage/_runtime/frontage-compiler.wasm +0 -0
- frontage/_runtime/frontage.wasm +0 -0
- frontage/_runtime/glue.js +464 -0
- frontage/_runtime/island.js +100 -0
- frontage/_stdlib/README.md +23 -0
- frontage/_stdlib/contextlib.py +266 -0
- frontage/a11y.py +69 -0
- frontage/aio.py +366 -0
- frontage/chart/README.md +201 -0
- frontage/chart/__init__.py +51 -0
- frontage/chart/_browser/canvas.js +1633 -0
- frontage/chart/_browser/index.css +12 -0
- frontage/chart/_browser/index.js +92 -0
- frontage/chart/canvas.py +236 -0
- frontage/chart/expr.py +338 -0
- frontage/chart/grammar.py +1845 -0
- frontage/chart/pen.py +437 -0
- frontage/chart/plot.py +78 -0
- frontage/chart/stats.py +101 -0
- frontage/chart/timeunit.py +153 -0
- frontage/chart/transform.py +107 -0
- frontage/chart/vega.py +61 -0
- frontage/chat/README.md +86 -0
- frontage/chat/__init__.py +250 -0
- frontage/chat/_browser/index.css +55 -0
- frontage/chat/_browser/index.js +47 -0
- frontage/chat/_server.py +130 -0
- frontage/chat/server.py +10 -0
- frontage/chat/style.py +63 -0
- frontage/chunks.py +180 -0
- frontage/cli/__init__.py +85 -0
- frontage/cli/_cache.py +14 -0
- frontage/cli/build.py +454 -0
- frontage/cli/check.py +74 -0
- frontage/cli/frontage_rt.py +235 -0
- frontage/cli/graph.py +292 -0
- frontage/cli/prerender.py +660 -0
- frontage/cli/serve.py +838 -0
- frontage/cli/site.py +721 -0
- frontage/cli/tailwind.py +89 -0
- frontage/content/__init__.py +442 -0
- frontage/debug.py +21 -0
- frontage/dev.py +219 -0
- frontage/devtools.py +114 -0
- frontage/dom.py +736 -0
- frontage/dsp/README.md +45 -0
- frontage/dsp/__init__.py +101 -0
- frontage/dsp/_browser/dsp.wasm +0 -0
- frontage/dsp/_browser/index.js +89 -0
- frontage/errors.py +37 -0
- frontage/flow.py +425 -0
- frontage/head.py +191 -0
- frontage/i18n.py +78 -0
- frontage/island.py +271 -0
- frontage/layout/README.md +33 -0
- frontage/layout/__init__.py +125 -0
- frontage/layout/_browser/index.css +48 -0
- frontage/layout/_browser/index.js +4 -0
- frontage/layout/style.py +56 -0
- frontage/lsp/__init__.py +28 -0
- frontage/lsp/data.py +424 -0
- frontage/lsp/documents.py +143 -0
- frontage/lsp/features.py +360 -0
- frontage/lsp/protocol.py +125 -0
- frontage/lsp/rules.py +320 -0
- frontage/lsp/scanner.py +545 -0
- frontage/lsp/server.py +240 -0
- frontage/map/README.md +93 -0
- frontage/map/__init__.py +18 -0
- frontage/map/_browser/index.css +667 -0
- frontage/map/_browser/index.js +108 -0
- frontage/map/_browser/leaflet.js +17 -0
- frontage/map/map.py +71 -0
- frontage/reactive.py +1427 -0
- frontage/remote/README.md +187 -0
- frontage/remote/__init__.py +9 -0
- frontage/remote/_browser/index.js +40 -0
- frontage/remote/_server.py +720 -0
- frontage/remote/client.py +296 -0
- frontage/remote/server.py +15 -0
- frontage/renderer.py +521 -0
- frontage/router.py +968 -0
- frontage/runtime.py +124 -0
- frontage/schema/README.md +146 -0
- frontage/schema/__init__.py +912 -0
- frontage/schema/_browser/index.css +3 -0
- frontage/schema/_browser/index.js +5 -0
- frontage/schema/_compile.py +106 -0
- frontage/schema/form.py +152 -0
- frontage/schema/jsonschema.py +223 -0
- frontage/state.py +124 -0
- frontage/state.pyi +22 -0
- frontage/store.py +297 -0
- frontage/supabase/README.md +155 -0
- frontage/supabase/__init__.py +27 -0
- frontage/supabase/_browser/index.js +7 -0
- frontage/supabase/client.py +254 -0
- frontage/supabase/query.py +241 -0
- frontage/supabase/realtime.py +187 -0
- frontage/table/README.md +57 -0
- frontage/table/__init__.py +234 -0
- frontage/table/_browser/index.css +40 -0
- frontage/table/_browser/index.js +4 -0
- frontage/table/style.py +44 -0
- frontage/template.py +225 -0
- frontage/testing.py +528 -0
- frontage/version.py +3 -0
- frontage/view.py +1063 -0
- frontage/widgets.py +139 -0
- frontage-0.16.1.dist-info/METADATA +255 -0
- frontage-0.16.1.dist-info/RECORD +142 -0
- frontage-0.16.1.dist-info/WHEEL +4 -0
- frontage-0.16.1.dist-info/entry_points.txt +3 -0
- frontage-0.16.1.dist-info/licenses/LICENSE +202 -0
- frontage-0.16.1.dist-info/licenses/NOTICE +11 -0
- frontage_server/__init__.py +1459 -0
- frontage_server/_binary.py +86 -0
- frontage_server/_cpython/__init__.py +333 -0
- frontage_server/_cpython/__main__.py +5 -0
- frontage_server/_cpython/host.py +106 -0
- frontage_server/_cpython/http.py +66 -0
- frontage_server/_cpython/turso.py +83 -0
- frontage_server/_cpython/upload.py +21 -0
- frontage_server/_scope.py +84 -0
- frontage_server/client.py +265 -0
- frontage_server/cors.py +62 -0
- frontage_server/db.py +122 -0
- frontage_server/depends.py +92 -0
- frontage_server/docs.py +196 -0
- frontage_server/openapi.py +232 -0
- frontage_server/pages.py +141 -0
- frontage_server/routing.py +276 -0
- frontage_server/session.py +186 -0
- frontage_server/streaming.py +161 -0
- frontage_server/testing.py +185 -0
- frontage_server/upload.py +160 -0
frontage/__init__.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Frontage: a fine-grained reactive UI framework for Python in the browser.
|
|
2
|
+
|
|
3
|
+
M5 of the rewrite (see project/design/architecture.md): the reactive core, the store, reactive views with the
|
|
4
|
+
insert rules, templates (`h` and `html(t"…")`), control flow and boundaries, Resource and
|
|
5
|
+
Action, the router, widgets, State, delegated events, and the DOM renderer.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from ._exports import EXPORTS
|
|
11
|
+
from .version import __version__
|
|
12
|
+
|
|
13
|
+
__all__ = sorted(EXPORTS) + ["__version__"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def __getattr__(name):
|
|
17
|
+
"""`from frontage import Signal` loads `frontage.reactive` and nothing else.
|
|
18
|
+
|
|
19
|
+
The package used to import every module up front, so a counter shipped the router, the
|
|
20
|
+
store and the template parser. Resolving names on first use (PEP 562, which MicroPython
|
|
21
|
+
supports) is what lets `frontage build` pack only the modules a page reaches — the table
|
|
22
|
+
in `_exports.py` is what both this function and the build read.
|
|
23
|
+
"""
|
|
24
|
+
module = EXPORTS.get(name)
|
|
25
|
+
if module is None:
|
|
26
|
+
# `from . import reactive` inside the package: CPython resolves a submodule itself when
|
|
27
|
+
# the attribute is missing, MicroPython asks here first. A name that is neither a
|
|
28
|
+
# public name nor a module is the usual AttributeError.
|
|
29
|
+
try:
|
|
30
|
+
__import__("frontage." + name)
|
|
31
|
+
except ImportError:
|
|
32
|
+
raise AttributeError("module 'frontage' has no attribute '%s'" % name) from None
|
|
33
|
+
return sys.modules["frontage." + name]
|
|
34
|
+
qualified = "frontage." + module
|
|
35
|
+
__import__(qualified)
|
|
36
|
+
value = getattr(sys.modules[qualified], name)
|
|
37
|
+
globals()[name] = value # resolved once; the next access is a plain lookup
|
|
38
|
+
return value
|
frontage/__init__.pyi
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Generated from _exports.py by `tools/exports.py`: the static view of the lazy package,
|
|
2
|
+
# for editors and ty.
|
|
3
|
+
|
|
4
|
+
from .aio import Action as Action
|
|
5
|
+
from .aio import Resource as Resource
|
|
6
|
+
from .aio import interval as interval
|
|
7
|
+
from .aio import poll as poll
|
|
8
|
+
from .errors import FrontageError as FrontageError
|
|
9
|
+
from .errors import NotReady as NotReady
|
|
10
|
+
from .errors import RenderError as RenderError
|
|
11
|
+
from .errors import format_exception as format_exception
|
|
12
|
+
from .flow import Dynamic as Dynamic
|
|
13
|
+
from .flow import Errored as Errored
|
|
14
|
+
from .flow import For as For
|
|
15
|
+
from .flow import Loading as Loading
|
|
16
|
+
from .flow import Match as Match
|
|
17
|
+
from .flow import Portal as Portal
|
|
18
|
+
from .flow import Show as Show
|
|
19
|
+
from .flow import Switch as Switch
|
|
20
|
+
from .head import Meta as Meta
|
|
21
|
+
from .head import Title as Title
|
|
22
|
+
from .island import island as island
|
|
23
|
+
from .reactive import Context as Context
|
|
24
|
+
from .reactive import Effect as Effect
|
|
25
|
+
from .reactive import Memo as Memo
|
|
26
|
+
from .reactive import Optimistic as Optimistic
|
|
27
|
+
from .reactive import Owner as Owner
|
|
28
|
+
from .reactive import RenderEffect as RenderEffect
|
|
29
|
+
from .reactive import Signal as Signal
|
|
30
|
+
from .reactive import Transition as Transition
|
|
31
|
+
from .reactive import batch as batch
|
|
32
|
+
from .reactive import get_owner as get_owner
|
|
33
|
+
from .reactive import is_pending as is_pending
|
|
34
|
+
from .reactive import latest as latest
|
|
35
|
+
from .reactive import on as on
|
|
36
|
+
from .reactive import on_cleanup as on_cleanup
|
|
37
|
+
from .reactive import on_mount as on_mount
|
|
38
|
+
from .reactive import provide as provide
|
|
39
|
+
from .reactive import refresh as refresh
|
|
40
|
+
from .reactive import run_with_owner as run_with_owner
|
|
41
|
+
from .reactive import selector as selector
|
|
42
|
+
from .reactive import spawn as spawn
|
|
43
|
+
from .reactive import transition as transition
|
|
44
|
+
from .reactive import tree as tree
|
|
45
|
+
from .reactive import untrack as untrack
|
|
46
|
+
from .reactive import use as use
|
|
47
|
+
from .reactive import use_transition as use_transition
|
|
48
|
+
from .renderer import HtmlRenderer as HtmlRenderer
|
|
49
|
+
from .renderer import RecordingRenderer as RecordingRenderer
|
|
50
|
+
from .renderer import Renderer as Renderer
|
|
51
|
+
from .router import A as A
|
|
52
|
+
from .router import ActionForm as ActionForm
|
|
53
|
+
from .router import Navigate as Navigate
|
|
54
|
+
from .router import Redirect as Redirect
|
|
55
|
+
from .router import Route as Route
|
|
56
|
+
from .router import Router as Router
|
|
57
|
+
from .router import use_location as use_location
|
|
58
|
+
from .router import use_navigate as use_navigate
|
|
59
|
+
from .router import use_params as use_params
|
|
60
|
+
from .router import use_query as use_query
|
|
61
|
+
from .runtime import in_browser as in_browser
|
|
62
|
+
from .runtime import platform as platform
|
|
63
|
+
from .state import State as State
|
|
64
|
+
from .state import computed as computed
|
|
65
|
+
from .state import field as field
|
|
66
|
+
from .store import Store as Store
|
|
67
|
+
from .store import reconcile as reconcile
|
|
68
|
+
from .store import snapshot as snapshot
|
|
69
|
+
from .template import html as html
|
|
70
|
+
from .version import __version__ as __version__
|
|
71
|
+
from .view import Element as Element
|
|
72
|
+
from .view import Mounted as Mounted
|
|
73
|
+
from .view import NodeRef as NodeRef
|
|
74
|
+
from .view import Text as Text
|
|
75
|
+
from .view import build as build
|
|
76
|
+
from .view import comment as comment
|
|
77
|
+
from .view import component as component
|
|
78
|
+
from .view import emit as emit
|
|
79
|
+
from .view import h as h
|
|
80
|
+
from .view import mount as mount
|
|
81
|
+
from .view import render_to_string as render_to_string
|
|
82
|
+
from .view import text as text
|
|
83
|
+
from .view import unique_id as unique_id
|
|
84
|
+
|
|
85
|
+
__all__: list[str]
|
frontage/__main__.py
ADDED
frontage/_bin/fpy.exe
ADDED
|
Binary file
|
frontage/_exports.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# The public names of `frontage`, and the module each lives in. One table, two readers:
|
|
2
|
+
# `frontage/__init__.py` resolves `from frontage import Signal` through it on first use
|
|
3
|
+
# (PEP 562, so a page loads only the modules it reaches), and `frontage build`'s import
|
|
4
|
+
# walk attributes the same name to the same module without importing anything. Keep it
|
|
5
|
+
# sorted by module, then name; `__init__.pyi` is generated from it by `mk exports`.
|
|
6
|
+
|
|
7
|
+
EXPORTS = {
|
|
8
|
+
"Action": "aio",
|
|
9
|
+
"Resource": "aio",
|
|
10
|
+
"interval": "aio",
|
|
11
|
+
"poll": "aio",
|
|
12
|
+
"FrontageError": "errors",
|
|
13
|
+
"NotReady": "errors",
|
|
14
|
+
"RenderError": "errors",
|
|
15
|
+
"format_exception": "errors",
|
|
16
|
+
"Dynamic": "flow",
|
|
17
|
+
"Errored": "flow",
|
|
18
|
+
"For": "flow",
|
|
19
|
+
"Loading": "flow",
|
|
20
|
+
"Match": "flow",
|
|
21
|
+
"Portal": "flow",
|
|
22
|
+
"Show": "flow",
|
|
23
|
+
"Switch": "flow",
|
|
24
|
+
"Meta": "head",
|
|
25
|
+
"Title": "head",
|
|
26
|
+
"island": "island",
|
|
27
|
+
"Context": "reactive",
|
|
28
|
+
"Effect": "reactive",
|
|
29
|
+
"Memo": "reactive",
|
|
30
|
+
"Optimistic": "reactive",
|
|
31
|
+
"Owner": "reactive",
|
|
32
|
+
"RenderEffect": "reactive",
|
|
33
|
+
"Signal": "reactive",
|
|
34
|
+
"Transition": "reactive",
|
|
35
|
+
"batch": "reactive",
|
|
36
|
+
"get_owner": "reactive",
|
|
37
|
+
"is_pending": "reactive",
|
|
38
|
+
"latest": "reactive",
|
|
39
|
+
"on": "reactive",
|
|
40
|
+
"on_cleanup": "reactive",
|
|
41
|
+
"on_mount": "reactive",
|
|
42
|
+
"provide": "reactive",
|
|
43
|
+
"refresh": "reactive",
|
|
44
|
+
"run_with_owner": "reactive",
|
|
45
|
+
"selector": "reactive",
|
|
46
|
+
"spawn": "reactive",
|
|
47
|
+
"transition": "reactive",
|
|
48
|
+
"tree": "reactive",
|
|
49
|
+
"untrack": "reactive",
|
|
50
|
+
"use": "reactive",
|
|
51
|
+
"use_transition": "reactive",
|
|
52
|
+
"HtmlRenderer": "renderer",
|
|
53
|
+
"RecordingRenderer": "renderer",
|
|
54
|
+
"Renderer": "renderer",
|
|
55
|
+
"A": "router",
|
|
56
|
+
"ActionForm": "router",
|
|
57
|
+
"Navigate": "router",
|
|
58
|
+
"Redirect": "router",
|
|
59
|
+
"Route": "router",
|
|
60
|
+
"Router": "router",
|
|
61
|
+
"use_location": "router",
|
|
62
|
+
"use_navigate": "router",
|
|
63
|
+
"use_params": "router",
|
|
64
|
+
"use_query": "router",
|
|
65
|
+
"in_browser": "runtime",
|
|
66
|
+
"platform": "runtime",
|
|
67
|
+
"State": "state",
|
|
68
|
+
"computed": "state",
|
|
69
|
+
"field": "state",
|
|
70
|
+
"Store": "store",
|
|
71
|
+
"reconcile": "store",
|
|
72
|
+
"snapshot": "store",
|
|
73
|
+
"html": "template",
|
|
74
|
+
"Element": "view",
|
|
75
|
+
"Mounted": "view",
|
|
76
|
+
"NodeRef": "view",
|
|
77
|
+
"Text": "view",
|
|
78
|
+
"build": "view",
|
|
79
|
+
"comment": "view",
|
|
80
|
+
"component": "view",
|
|
81
|
+
"emit": "view",
|
|
82
|
+
"h": "view",
|
|
83
|
+
"mount": "view",
|
|
84
|
+
"render_to_string": "view",
|
|
85
|
+
"text": "view",
|
|
86
|
+
"unique_id": "view",
|
|
87
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Boot a page on frontage's runtime: the wasm, the compiled modules named in
|
|
2
|
+
// `manifest.json`, then the entry as `__main__`. The page declares what to run:
|
|
3
|
+
//
|
|
4
|
+
// <script type="module" src="./_frontage/boot.js" data-fr-boot data-fr-entry="counter"></script>
|
|
5
|
+
//
|
|
6
|
+
// `data-fr-compiler` on the tag loads `frontage-compiler.wasm` instead, the same runtime with
|
|
7
|
+
// the compiler in it, for a page that runs a program someone types (the playground).
|
|
8
|
+
// Everything resolves from `import.meta.url`, so a page at any depth finds its runtime.
|
|
9
|
+
|
|
10
|
+
import { load } from "./glue.js";
|
|
11
|
+
|
|
12
|
+
const asset = (name) => new URL(name, import.meta.url).href;
|
|
13
|
+
let rtAssets = "";
|
|
14
|
+
|
|
15
|
+
async function bytes(url) {
|
|
16
|
+
const response = await fetch(url);
|
|
17
|
+
if (!response.ok) throw new Error(`frontage: ${response.status} fetching ${url}`);
|
|
18
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const console_io = {
|
|
22
|
+
stdout: (s) => console.log(s.replace(/\n$/, "")),
|
|
23
|
+
stderr: (s) => console.error(s.replace(/\n$/, "")),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The runtime with the compiler in it and no application: for a page that holds its program
|
|
28
|
+
* in a URL fragment or a text box (the runner, the playground) and has nothing to fetch.
|
|
29
|
+
* `rt.runSource(code)` runs it as `__main__`. Deliberately touches nothing in the document.
|
|
30
|
+
*/
|
|
31
|
+
export async function startRuntime() {
|
|
32
|
+
const [rt, framework] = await Promise.all([
|
|
33
|
+
load(asset("frontage-compiler.wasm"), console_io),
|
|
34
|
+
fetch(asset("framework.json")).then((r) => r.json()),
|
|
35
|
+
]);
|
|
36
|
+
await addModules(rt, framework.modules);
|
|
37
|
+
return rt;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// A built app's manifest names each module's content-hashed file; the dev server's does not.
|
|
41
|
+
let files = {};
|
|
42
|
+
const fileOf = (name) => files[name] || `${name}.fbc`;
|
|
43
|
+
|
|
44
|
+
async function addModules(rt, names) {
|
|
45
|
+
const modules = await Promise.all(names.map(async (name) => [name, await bytes(asset(fileOf(name)))]));
|
|
46
|
+
for (const [name, fbc] of modules) rt.addModule(name, fbc);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The runtime, this page's modules, and the JavaScript libraries the tag declares. `run`
|
|
51
|
+
* picks, from the manifest, the file whose bytecode becomes `__main__` once everything is
|
|
52
|
+
* in: an app's entry, or — for a page of islands, which has no entry to run —
|
|
53
|
+
* `frontage.island`.
|
|
54
|
+
*/
|
|
55
|
+
async function start(tag, run) {
|
|
56
|
+
// A page that runs a typed program (`data-fr-compiler`) gets the whole framework, since
|
|
57
|
+
// the program may import any of it; a built app gets its entry's import closure.
|
|
58
|
+
const compiler = tag !== null && tag.dataset.frCompiler !== undefined;
|
|
59
|
+
const [manifest, framework] = await Promise.all([
|
|
60
|
+
fetch(asset("manifest.json")).then((r) => r.json()),
|
|
61
|
+
compiler ? fetch(asset("framework.json")).then((r) => r.json()) : { modules: [] },
|
|
62
|
+
]);
|
|
63
|
+
files = manifest.files || {};
|
|
64
|
+
// What a chunk fetch needs later: where these files live, and which modules are in each.
|
|
65
|
+
rtAssets = asset("");
|
|
66
|
+
const rt = await load(asset(compiler ? "frontage-compiler.wasm" : manifest.wasm || "frontage.wasm"), console_io);
|
|
67
|
+
const names = [...new Set([...framework.modules, ...manifest.modules])];
|
|
68
|
+
await addModules(rt, names);
|
|
69
|
+
// JavaScript modules the app asked for (`data-fr-js="name=./lib.js, ./other.js"`): the
|
|
70
|
+
// glue around a C or Rust library compiled to WebAssembly. Named ones become Python
|
|
71
|
+
// modules. Resolved from `../` of this file, the app's own directory in every layout.
|
|
72
|
+
const appRoot = new URL("../", import.meta.url);
|
|
73
|
+
for (const item of ((tag && tag.dataset.frJs) || "").split(",")) {
|
|
74
|
+
const spec = item.trim();
|
|
75
|
+
if (!spec) continue;
|
|
76
|
+
const eq = spec.indexOf("=");
|
|
77
|
+
const name = eq > 0 ? spec.slice(0, eq).trim() : "";
|
|
78
|
+
const specifier = eq > 0 ? spec.slice(eq + 1).trim() : spec;
|
|
79
|
+
const namespace = await import(new URL(specifier, appRoot).href);
|
|
80
|
+
if (name) rt.registerJsModule(name, namespace);
|
|
81
|
+
}
|
|
82
|
+
const main = await bytes(asset(run(manifest)));
|
|
83
|
+
rt.assetBase = rtAssets;
|
|
84
|
+
rt.manifest = manifest;
|
|
85
|
+
window.frontage = rt;
|
|
86
|
+
const code = rt.run(main);
|
|
87
|
+
if (code === 1) console.error("frontage: the entry raised; see above");
|
|
88
|
+
return rt;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* A static page whose islands have started asking for a runtime (`island.js`). There is no
|
|
93
|
+
* entry to run — the page's HTML was written at build time — so what runs is
|
|
94
|
+
* `frontage.island`, which mounts each queued wrapper over the markup already on screen.
|
|
95
|
+
* Called once per page, however many islands there are.
|
|
96
|
+
*/
|
|
97
|
+
export async function startIslands() {
|
|
98
|
+
const tag = document.querySelector("script[data-fr-islands]");
|
|
99
|
+
return start(tag, () => fileOf("frontage.island"));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function boot() {
|
|
103
|
+
const tag = document.querySelector("script[data-fr-boot]");
|
|
104
|
+
if (!tag) {
|
|
105
|
+
// Not an error: a page may import this module for `startRuntime` or `startIslands` alone.
|
|
106
|
+
if (!document.querySelector("script[data-fr-islands]")) {
|
|
107
|
+
console.warn("frontage: no <script data-fr-boot> on the page, so nothing was mounted");
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const entry = tag.dataset.frEntry || "app";
|
|
112
|
+
// `manifest.entry` is the built app's content-hashed entry file; the dev server's manifest
|
|
113
|
+
// has none, and the module is asked for by its plain name.
|
|
114
|
+
return start(tag, (manifest) => manifest.entry || `${entry}.fbc`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const parsed =
|
|
118
|
+
document.readyState === "loading"
|
|
119
|
+
? new Promise((done) => document.addEventListener("DOMContentLoaded", done, { once: true }))
|
|
120
|
+
: Promise.resolve();
|
|
121
|
+
|
|
122
|
+
export const ready = parsed.then(boot);
|
|
123
|
+
ready.catch((error) => {
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
throw error;
|
|
126
|
+
});
|
|
127
|
+
});
|
|
Binary file
|
|
Binary file
|