spaday-regular-table 0.2.1__tar.gz → 0.3.0__tar.gz

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.
Files changed (49) hide show
  1. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/PKG-INFO +15 -3
  2. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/README.md +13 -1
  3. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/build.mjs +17 -0
  4. spaday_regular_table-0.3.0/js/examples/build_pyodide_example.py +48 -0
  5. spaday_regular_table-0.3.0/js/examples/pyodide-worker.js +100 -0
  6. spaday_regular_table-0.3.0/js/examples/pyodide.html +151 -0
  7. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/package.json +8 -8
  8. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/playwright.config.js +12 -6
  9. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/pnpm-lock.yaml +166 -166
  10. spaday_regular_table-0.3.0/js/src/css/theme.css +112 -0
  11. spaday_regular_table-0.3.0/js/src/ts/define-guard.ts +42 -0
  12. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/src/ts/index.ts +2 -1
  13. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tests/index.spec.js +20 -0
  14. spaday_regular_table-0.3.0/js/tests/pyodide.spec.js +29 -0
  15. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/pyproject.toml +3 -3
  16. spaday_regular_table-0.3.0/spaday_regular_table/__init__.py +66 -0
  17. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/example.py +3 -1
  18. spaday_regular_table-0.3.0/spaday_regular_table/extension/cdn/index.js +2 -0
  19. spaday_regular_table-0.3.0/spaday_regular_table/extension/cdn/index.js.map +7 -0
  20. spaday_regular_table-0.3.0/spaday_regular_table/extension/css/theme.css +1 -0
  21. spaday_regular_table-0.3.0/spaday_regular_table/extension/versions.json +3 -0
  22. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/tests/test_all.py +13 -1
  23. spaday_regular_table-0.3.0/spaday_regular_table/tests/test_versions.py +18 -0
  24. spaday_regular_table-0.2.1/js/src/css/theme.css +0 -51
  25. spaday_regular_table-0.2.1/js/src/ts/define-guard.ts +0 -19
  26. spaday_regular_table-0.2.1/spaday_regular_table/__init__.py +0 -50
  27. spaday_regular_table-0.2.1/spaday_regular_table/extension/cdn/index.js +0 -2
  28. spaday_regular_table-0.2.1/spaday_regular_table/extension/cdn/index.js.map +0 -7
  29. spaday_regular_table-0.2.1/spaday_regular_table/extension/css/theme.css +0 -1
  30. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/.gitignore +0 -0
  31. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/LICENSE +0 -0
  32. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/.oxfmtrc.json +0 -0
  33. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/.oxlintrc.json +0 -0
  34. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/pnpm-workspace.yaml +0 -0
  35. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/src/css/index.css +0 -0
  36. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/src/html/index.html +0 -0
  37. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/src/ts/css.d.ts +0 -0
  38. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tools/bundle.mjs +0 -0
  39. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tools/css.mjs +0 -0
  40. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tools/externals.mjs +0 -0
  41. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tools/getarg.mjs +0 -0
  42. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tools/html.mjs +0 -0
  43. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/js/tsconfig.json +0 -0
  44. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/components.cem.json +0 -0
  45. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/components.py +0 -0
  46. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/extension/css/index.css +0 -0
  47. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/extension/css/material.css +0 -0
  48. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/extension/index.html +0 -0
  49. {spaday_regular_table-0.2.1 → spaday_regular_table-0.3.0}/spaday_regular_table/tests/test_example.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: spaday-regular-table
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: regular-table for spaday
5
5
  Project-URL: Repository, https://github.com/1kbgz/spaday-regular-table
6
6
  Project-URL: Homepage, https://github.com/1kbgz/spaday-regular-table
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.14
17
17
  Classifier: Programming Language :: Python :: Implementation :: CPython
18
18
  Classifier: Programming Language :: Python :: Implementation :: PyPy
19
19
  Requires-Python: >=3.11
20
- Requires-Dist: spaday<1.0,>=0.6.0
20
+ Requires-Dist: spaday<1.0,>=0.11.1
21
21
  Provides-Extra: develop
22
22
  Requires-Dist: build; extra == 'develop'
23
23
  Requires-Dist: bump-my-version; extra == 'develop'
@@ -42,7 +42,12 @@ Requires-Dist: starlette; extra == 'examples'
42
42
  Requires-Dist: uvicorn; extra == 'examples'
43
43
  Description-Content-Type: text/markdown
44
44
 
45
- # spaday-regular-table
45
+ <a href="https://github.com/1kbgz/spaday-regular-table">
46
+ <picture>
47
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/1kbgz/spaday-regular-table/raw/main/docs/img/logo-dark.webp?raw=true">
48
+ <img alt="spaday-regular-table logo, a table with a data-grid top inside a browser window" src="https://github.com/1kbgz/spaday-regular-table/raw/main/docs/img/logo-light.webp?raw=true" width="800">
49
+ </picture>
50
+ </a>
46
51
 
47
52
  Viewport-virtualized data tables for spaday, powered by `regular-table`.
48
53
 
@@ -51,6 +56,8 @@ Viewport-virtualized data tables for spaday, powered by `regular-table`.
51
56
  [![License](https://img.shields.io/github/license/1kbgz/spaday-regular-table)](https://github.com/1kbgz/spaday-regular-table)
52
57
  [![PyPI](https://img.shields.io/pypi/v/spaday-regular-table.svg)](https://pypi.python.org/pypi/spaday-regular-table)
53
58
 
59
+ [![Preview of regular-table page](https://raw.githubusercontent.com/1kbgz/spaday-regular-table/main/docs/img/preview.webp)](./spaday_regular_table/example.py)
60
+
54
61
  ## Documentation
55
62
 
56
63
  - [Build a 100,000-row table](docs/src/tutorial.md) — guided virtual-table example.
@@ -99,6 +106,8 @@ browser methods remain available to integration authors, but applications need n
99
106
 
100
107
  ## Run the local example
101
108
 
109
+ [Run the complete example in your browser](https://1kbgz.github.io/spaday-regular-table/lite/) — Python runs locally through Pyodide; no install or server required.
110
+
102
111
  ```bash
103
112
  python -m pip install -e ".[examples]"
104
113
  python -m spaday_regular_table.example
@@ -109,3 +118,6 @@ virtualized rows, a server row stream, full-width sizing, rich cells, and server
109
118
  insert, remove, and click operations. All interaction is authored in Python; there is no companion
110
119
  `example.js`. It passes the local package descriptor directly, so it does not install or resolve the
111
120
  integration from GitHub.
121
+
122
+ > [!NOTE]
123
+ > This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
@@ -1,4 +1,9 @@
1
- # spaday-regular-table
1
+ <a href="https://github.com/1kbgz/spaday-regular-table">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/1kbgz/spaday-regular-table/raw/main/docs/img/logo-dark.webp?raw=true">
4
+ <img alt="spaday-regular-table logo, a table with a data-grid top inside a browser window" src="https://github.com/1kbgz/spaday-regular-table/raw/main/docs/img/logo-light.webp?raw=true" width="800">
5
+ </picture>
6
+ </a>
2
7
 
3
8
  Viewport-virtualized data tables for spaday, powered by `regular-table`.
4
9
 
@@ -7,6 +12,8 @@ Viewport-virtualized data tables for spaday, powered by `regular-table`.
7
12
  [![License](https://img.shields.io/github/license/1kbgz/spaday-regular-table)](https://github.com/1kbgz/spaday-regular-table)
8
13
  [![PyPI](https://img.shields.io/pypi/v/spaday-regular-table.svg)](https://pypi.python.org/pypi/spaday-regular-table)
9
14
 
15
+ [![Preview of regular-table page](https://raw.githubusercontent.com/1kbgz/spaday-regular-table/main/docs/img/preview.webp)](./spaday_regular_table/example.py)
16
+
10
17
  ## Documentation
11
18
 
12
19
  - [Build a 100,000-row table](docs/src/tutorial.md) — guided virtual-table example.
@@ -55,6 +62,8 @@ browser methods remain available to integration authors, but applications need n
55
62
 
56
63
  ## Run the local example
57
64
 
65
+ [Run the complete example in your browser](https://1kbgz.github.io/spaday-regular-table/lite/) — Python runs locally through Pyodide; no install or server required.
66
+
58
67
  ```bash
59
68
  python -m pip install -e ".[examples]"
60
69
  python -m spaday_regular_table.example
@@ -65,3 +74,6 @@ virtualized rows, a server row stream, full-width sizing, rich cells, and server
65
74
  insert, remove, and click operations. All interaction is authored in Python; there is no companion
66
75
  `example.js`. It passes the local package descriptor directly, so it does not install or resolve the
67
76
  integration from GitHub.
77
+
78
+ > [!NOTE]
79
+ > This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
@@ -42,6 +42,23 @@ async function build() {
42
42
 
43
43
  await Promise.all(BUNDLES.map(bundle)).catch(() => process.exit(1));
44
44
 
45
+ // the exact version of every library this package serves, read by the Python package as its
46
+ // ComponentPackage.provides, so spaday can reconcile it with the other packages on a page
47
+ const { dependencies = {} } = JSON.parse(
48
+ fs.readFileSync("package.json", "utf8"),
49
+ );
50
+ const served = Object.fromEntries(
51
+ Object.keys(dependencies).map((name) => [
52
+ name,
53
+ JSON.parse(fs.readFileSync(`node_modules/${name}/package.json`, "utf8"))
54
+ .version,
55
+ ]),
56
+ );
57
+ fs.writeFileSync(
58
+ "dist/versions.json",
59
+ `${JSON.stringify(served, null, 2)}\n`,
60
+ );
61
+
45
62
  // Copy servable assets to python extension (exclude esm/)
46
63
  fs.mkdirSync("../spaday_regular_table/extension", { recursive: true });
47
64
  await cpy("dist/**/*", "../spaday_regular_table/extension", {
@@ -0,0 +1,48 @@
1
+ """Assemble the static Pyodide example from locally built and downloaded wheels."""
2
+
3
+ import json
4
+ import shutil
5
+ import sys
6
+ import zipfile
7
+ from pathlib import Path
8
+
9
+
10
+ def copy_wheel(wheel: Path, output: Path) -> str:
11
+ target = output / "pypi" / wheel.name
12
+ target.parent.mkdir(parents=True, exist_ok=True)
13
+ shutil.copy2(wheel, target)
14
+ return f"pypi/{wheel.name}"
15
+
16
+
17
+ def extract_assets(wheel: Path, package: str, output: Path) -> None:
18
+ prefix = f"{package}/extension/"
19
+ with zipfile.ZipFile(wheel) as archive:
20
+ assets = [name for name in archive.namelist() if name.startswith(prefix) and not name.endswith("/")]
21
+ if not assets:
22
+ raise RuntimeError(f"{wheel.name} contains no browser assets")
23
+ for name in assets:
24
+ target = output / name.removeprefix(prefix)
25
+ target.parent.mkdir(parents=True, exist_ok=True)
26
+ target.write_bytes(archive.read(name))
27
+
28
+
29
+ def one_wheel(directory: Path, distribution: str) -> Path:
30
+ wheels = list(directory.glob(f"{distribution}-*.whl"))
31
+ if len(wheels) != 1:
32
+ raise RuntimeError(f"expected one {distribution} wheel in {directory}, found {len(wheels)}")
33
+ return wheels[0]
34
+
35
+
36
+ def main(output: Path, table_wheel: Path, dependency_dir: Path) -> None:
37
+ spaday_wheel = one_wheel(dependency_dir, "spaday")
38
+ wheels = {
39
+ "table": copy_wheel(table_wheel, output),
40
+ "spaday": copy_wheel(spaday_wheel, output),
41
+ }
42
+ extract_assets(table_wheel, "spaday_regular_table", output / "components" / "regular-table")
43
+ extract_assets(spaday_wheel, "spaday", output / "runtime" / "spaday")
44
+ (output / "wheels.json").write_text(json.dumps(wheels, indent=2) + "\n")
45
+
46
+
47
+ if __name__ == "__main__":
48
+ main(*(Path(value) for value in sys.argv[1:]))
@@ -0,0 +1,100 @@
1
+ const PYODIDE_VERSION = "314.0.4";
2
+ let pyodide;
3
+
4
+ const ready = (async () => {
5
+ self.postMessage({ type: "status", message: "Loading Pyodide…" });
6
+ const { loadPyodide } = await import(
7
+ `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/pyodide.mjs`
8
+ );
9
+ pyodide = await loadPyodide();
10
+ await pyodide.loadPackage(["micropip", "anyio"]);
11
+
12
+ self.postMessage({ type: "status", message: "Installing example…" });
13
+ const response = await fetch(new URL("./wheels.json", self.location.href));
14
+ if (!response.ok)
15
+ throw new Error(`wheel manifest returned ${response.status}`);
16
+ const wheels = await response.json();
17
+ const urls = Object.fromEntries(
18
+ Object.entries(wheels).map(([name, path]) => [
19
+ name,
20
+ new URL(path, self.location.href).href,
21
+ ]),
22
+ );
23
+ pyodide.globals.set("wheels_json", JSON.stringify(urls));
24
+ return pyodide.runPythonAsync(`
25
+ import asyncio
26
+ import json
27
+ import micropip
28
+
29
+ wheels = json.loads(wheels_json)
30
+ await micropip.install([wheels["spaday"], "starlette", "uvicorn"])
31
+ await micropip.install(wheels["table"], deps=False)
32
+
33
+ from spaday_regular_table import example
34
+
35
+ pending_patches = []
36
+ native_publish = example.publish
37
+
38
+ def publish(*operations):
39
+ patch = native_publish(*operations)
40
+ pending_patches.append(patch)
41
+ return patch
42
+
43
+ example.publish = publish
44
+
45
+ def flush_stream():
46
+ patches = list(pending_patches)
47
+ pending_patches.clear()
48
+ return json.dumps(patches)
49
+
50
+ class LocalRequest:
51
+ def __init__(self, action, body):
52
+ self.path_params = {"action": action}
53
+ self._body = body
54
+
55
+ async def json(self):
56
+ return self._body
57
+
58
+ async def call_endpoint(action, body_json):
59
+ response = await example.table_action(LocalRequest(action, json.loads(body_json)))
60
+ return json.dumps({
61
+ "status": response.status_code,
62
+ "body": json.loads(bytes(response.body).decode()),
63
+ })
64
+
65
+ asyncio.create_task(example.stream_rows())
66
+
67
+ json.dumps({
68
+ "tree": example.page.to_node(),
69
+ "style": example.styles,
70
+ "store": example.initial_store,
71
+ })
72
+ `);
73
+ })();
74
+
75
+ let queue = Promise.resolve();
76
+
77
+ async function handle(message) {
78
+ const snapshot = await ready;
79
+ if (message.type === "start") {
80
+ self.postMessage({ type: "snapshot", payload: JSON.parse(snapshot) });
81
+ } else if (message.type === "flush") {
82
+ const patches = JSON.parse(pyodide.runPython("flush_stream()"));
83
+ if (patches.length) self.postMessage({ type: "stream", patches });
84
+ } else if (message.type === "endpoint") {
85
+ pyodide.globals.set("action", message.action);
86
+ pyodide.globals.set("body_json", JSON.stringify(message.body));
87
+ const result = JSON.parse(
88
+ await pyodide.runPythonAsync("await call_endpoint(action, body_json)"),
89
+ );
90
+ self.postMessage({ type: "endpoint", id: message.id, ...result });
91
+ }
92
+ }
93
+
94
+ self.addEventListener("message", (event) => {
95
+ queue = queue
96
+ .then(() => handle(event.data))
97
+ .catch((error) => {
98
+ self.postMessage({ type: "error", message: String(error) });
99
+ });
100
+ });
@@ -0,0 +1,151 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>spaday-regular-table in Pyodide</title>
7
+ <link rel="stylesheet" href="./components/regular-table/css/index.css" />
8
+ <link rel="stylesheet" href="./components/regular-table/css/material.css" />
9
+ <link rel="stylesheet" href="./components/regular-table/css/theme.css" />
10
+ <style>
11
+ #pyodide-status {
12
+ position: sticky;
13
+ z-index: 10000;
14
+ top: 0;
15
+ box-sizing: border-box;
16
+ min-height: 3rem;
17
+ padding: 0.75rem 1rem;
18
+ border-bottom: 1px solid #cbd5e1;
19
+ color: #475569;
20
+ background: #fffffff2;
21
+ font:
22
+ 14px/1.4 system-ui,
23
+ sans-serif;
24
+ backdrop-filter: blur(12px);
25
+ }
26
+ #pyodide-error {
27
+ margin: 1rem;
28
+ color: #b91c1c;
29
+ white-space: pre-wrap;
30
+ }
31
+ </style>
32
+ </head>
33
+ <body>
34
+ <div id="pyodide-status">Loading Python in the browser…</div>
35
+ <div id="example-root"></div>
36
+ <pre id="pyodide-error" hidden></pre>
37
+ <script type="module">
38
+ import { init, mount, Store } from "./runtime/spaday/cdn/index.js";
39
+ import "./components/regular-table/cdn/index.js";
40
+
41
+ const status = document.querySelector("#pyodide-status");
42
+ const pendingEndpoints = new Map();
43
+ const streamSources = new Set();
44
+ let nextEndpointId = 0;
45
+
46
+ class LocalEventSource extends EventTarget {
47
+ static CLOSED = 2;
48
+ static CONNECTING = 0;
49
+ static OPEN = 1;
50
+
51
+ constructor(url) {
52
+ super();
53
+ const path = new URL(url, location.href).pathname;
54
+ if (path !== "/api/table/stream")
55
+ throw new Error(`unsupported local event stream: ${path}`);
56
+ this.readyState = LocalEventSource.CONNECTING;
57
+ this.url = new URL(url, location.href).href;
58
+ streamSources.add(this);
59
+ queueMicrotask(() => {
60
+ this.readyState = LocalEventSource.OPEN;
61
+ this.dispatchEvent(new Event("open"));
62
+ });
63
+ }
64
+
65
+ close() {
66
+ this.readyState = LocalEventSource.CLOSED;
67
+ streamSources.delete(this);
68
+ }
69
+ }
70
+
71
+ globalThis.EventSource = LocalEventSource;
72
+
73
+ function fail(error) {
74
+ status.textContent = "Unable to start";
75
+ const output = document.querySelector("#pyodide-error");
76
+ output.hidden = false;
77
+ output.textContent = String(error);
78
+ }
79
+
80
+ try {
81
+ await init({ module_or_path: "./runtime/spaday/pkg/spaday_bg.wasm" });
82
+
83
+ const worker = new Worker("./pyodide-worker.js", { type: "module" });
84
+ const nativeFetch = globalThis.fetch.bind(globalThis);
85
+ globalThis.fetch = async (input, options = {}) => {
86
+ const url = new URL(
87
+ input instanceof Request ? input.url : input,
88
+ location.href,
89
+ );
90
+ const match = url.pathname.match(
91
+ /^\/api\/table\/(click|update|insert|remove)$/,
92
+ );
93
+ if (!match) return nativeFetch(input, options);
94
+
95
+ const id = ++nextEndpointId;
96
+ const response = new Promise((resolve) => {
97
+ pendingEndpoints.set(id, resolve);
98
+ });
99
+ worker.postMessage({
100
+ type: "endpoint",
101
+ id,
102
+ action: match[1],
103
+ body: options.body ? JSON.parse(String(options.body)) : null,
104
+ });
105
+ return response;
106
+ };
107
+
108
+ worker.addEventListener("message", (event) => {
109
+ if (event.data.type === "status")
110
+ status.textContent = event.data.message;
111
+ if (event.data.type === "error") fail(event.data.message);
112
+ if (event.data.type === "stream") {
113
+ for (const patch of event.data.patches) {
114
+ const message = new MessageEvent("message", {
115
+ data: JSON.stringify(patch),
116
+ });
117
+ for (const source of streamSources) source.dispatchEvent(message);
118
+ }
119
+ }
120
+ if (event.data.type === "endpoint") {
121
+ const resolve = pendingEndpoints.get(event.data.id);
122
+ if (resolve) {
123
+ pendingEndpoints.delete(event.data.id);
124
+ resolve(
125
+ new Response(JSON.stringify(event.data.body), {
126
+ status: event.data.status,
127
+ headers: { "content-type": "application/json" },
128
+ }),
129
+ );
130
+ }
131
+ }
132
+ if (event.data.type === "snapshot") {
133
+ const { tree, style, store: initialStore } = event.data.payload;
134
+ document.head.insertAdjacentHTML("beforeend", style);
135
+ const store = new Store(initialStore);
136
+ mount(document.querySelector("#example-root"), tree, store);
137
+ window.setInterval(
138
+ () => worker.postMessage({ type: "flush" }),
139
+ 100,
140
+ );
141
+ status.textContent = "Ready · Python model running in this browser";
142
+ document.documentElement.dataset.ready = "true";
143
+ }
144
+ });
145
+ worker.postMessage({ type: "start" });
146
+ } catch (error) {
147
+ fail(error);
148
+ }
149
+ </script>
150
+ </body>
151
+ </html>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spaday-regular-table",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "regular-table for spaday",
5
5
  "repository": "git@github.com:1kbgz/spaday-regular-table.git",
6
6
  "author": "1kbgz <dev@1kbgz.com>",
@@ -31,8 +31,8 @@
31
31
  "build": "npm-run-all build:prod build:types",
32
32
  "clean": "rm -rf dist playwright-report ../spaday_regular_table/extension",
33
33
  "dev": "npm-run-all -p start watch",
34
- "lint": "oxlint . && oxfmt --check \"src/**/*.{js,ts,jsx,tsx,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"",
35
- "fix": "oxlint --fix . && oxfmt --write \"src/**/*.{js,ts,jsx,tsx,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"",
34
+ "lint": "oxlint . && oxfmt --check \"examples/**/*.{js,html}\" \"src/**/*.{js,ts,jsx,tsx,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"",
35
+ "fix": "oxlint --fix . && oxfmt --write \"examples/**/*.{js,html}\" \"src/**/*.{js,ts,jsx,tsx,css}\" \"tests/**/*.{js,ts,jsx,tsx}\" \"*.mjs\" \"*.json\"",
36
36
  "preinstall": "npx only-allow pnpm",
37
37
  "prepack": "npm run build",
38
38
  "start": "http-server -p 3000 -o examples/",
@@ -44,15 +44,15 @@
44
44
  "regular-table": "=0.9.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@playwright/test": "^1.62.0",
47
+ "@playwright/test": "^1.62.1",
48
48
  "cpy": "^13.2.2",
49
- "esbuild": "^0.28.1",
49
+ "esbuild": "^0.28.2",
50
50
  "http-server": "^14.1.1",
51
51
  "lightningcss": "^1.33.0",
52
- "nodemon": "^3.1.10",
52
+ "nodemon": "^3.1.14",
53
53
  "npm-run-all": "^4.1.5",
54
- "oxfmt": "^0.63.0",
55
- "oxlint": "^1.78.0",
54
+ "oxfmt": "^0.66.0",
55
+ "oxlint": "^1.81.0",
56
56
  "typescript": "^7.0.2"
57
57
  }
58
58
  }
@@ -1,5 +1,7 @@
1
1
  import { defineConfig, devices } from "@playwright/test";
2
2
 
3
+ const pyodideOnly = process.env.SPADAY_REGULAR_TABLE_PYODIDE_ONLY === "1";
4
+
3
5
  export default defineConfig({
4
6
  testDir: "tests",
5
7
  fullyParallel: true,
@@ -28,11 +30,15 @@ export default defineConfig({
28
30
  reuseExistingServer: !process.env.CI,
29
31
  timeout: 120 * 1000,
30
32
  },
31
- {
32
- command: "python -m spaday_regular_table.example",
33
- url: "http://127.0.0.1:8014",
34
- reuseExistingServer: !process.env.CI,
35
- timeout: 120 * 1000,
36
- },
33
+ ...(pyodideOnly
34
+ ? []
35
+ : [
36
+ {
37
+ command: "python -m spaday_regular_table.example",
38
+ url: "http://127.0.0.1:8014",
39
+ reuseExistingServer: !process.env.CI,
40
+ timeout: 120 * 1000,
41
+ },
42
+ ]),
37
43
  ],
38
44
  });