kopular 0.21.0 → 0.21.2
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/LLM.md +27 -2
- package/package.json +2 -2
- package/src/testing.js +20 -7
package/LLM.md
CHANGED
|
@@ -169,6 +169,28 @@ FormField<string> email = new FormField<string>("", (string v) => Validators.Ema
|
|
|
169
169
|
`{ get; }`) — `extern class` supports a plain field declaration for exactly this case,
|
|
170
170
|
not just get/set accessor pairs.
|
|
171
171
|
|
|
172
|
+
`Computed1`/`Computed2`/`Resource<T>` (needs `kopscript >= 0.24.0` for `extern enum`,
|
|
173
|
+
which `AsyncStatus` requires):
|
|
174
|
+
|
|
175
|
+
```ks
|
|
176
|
+
extern class Computed1<A, R> {
|
|
177
|
+
constructor(state<A> source, (A) => R compute);
|
|
178
|
+
state<R> Value;
|
|
179
|
+
} from "kopular/computed";
|
|
180
|
+
extern class Computed2<A, B, R> {
|
|
181
|
+
constructor(state<A> a, state<B> b, (A, B) => R compute);
|
|
182
|
+
state<R> Value;
|
|
183
|
+
} from "kopular/computed";
|
|
184
|
+
|
|
185
|
+
extern enum AsyncStatus { Loading, Success, Failure } from "kopular/resource";
|
|
186
|
+
extern class Resource<T> {
|
|
187
|
+
constructor(task<T> operation);
|
|
188
|
+
state<AsyncStatus> Status;
|
|
189
|
+
state<T?> Data;
|
|
190
|
+
state<string?> Error;
|
|
191
|
+
} from "kopular/resource";
|
|
192
|
+
```
|
|
193
|
+
|
|
172
194
|
You also need your own ambient DOM `extern` block (`document`, `Element`, `Event`, ...) —
|
|
173
195
|
Kopular's own copy in `dom.ks` isn't reachable across the package boundary; redeclare the
|
|
174
196
|
handful of members you actually use. See KopularDemo's `src/kopular_bindings.ks` for a
|
|
@@ -636,7 +658,7 @@ import { runKopularApp } from "kopular/testing";
|
|
|
636
658
|
|
|
637
659
|
const { window, cleanup } = await runKopularApp(srcDir, "app.ks", {
|
|
638
660
|
includeKopularPackage: true, // app consumes Kopular via `extern`, not relative `using`
|
|
639
|
-
extraFiles: ["
|
|
661
|
+
extraFiles: ["config.json"], // any sibling with an extension besides .ks/.html/.js
|
|
640
662
|
fetchMock: (...args) => Promise.resolve({ ok: true, status: 200, text: () => Promise.resolve("body") }),
|
|
641
663
|
url: "http://localhost/",
|
|
642
664
|
});
|
|
@@ -650,7 +672,10 @@ try {
|
|
|
650
672
|
Compiles `entryFileName` (plus everything else in `srcDir` it `using`s) via kopscript's
|
|
651
673
|
`compileGraph`, binds jsdom onto `globalThis` (`document`/`Element`/`Event`/`location`/
|
|
652
674
|
`history`/`window`/`fetch`) for the compiled ambient `extern` declarations to find, and
|
|
653
|
-
runs it. `
|
|
675
|
+
runs it. Every `.ks`/`.html`/`.js` file in `srcDir` is copied along with it — `.js`
|
|
676
|
+
included specifically so a hand-written (not compiled) sibling like a `Router.AddLazyRoute`
|
|
677
|
+
loader shim just works with no extra setup; `extraFiles` is only for a real dependency with
|
|
678
|
+
some OTHER extension (e.g. a `.json` config file). `runKopularFixture(source, options)` is the sibling export for an inline fixture
|
|
654
679
|
string instead of a real file (used by Kopular's own test suite; copies Kopular's *own*
|
|
655
680
|
`.ks` sources alongside the fixture, so `using "./component"` resolves — only meaningful
|
|
656
681
|
for testing Kopular itself, not an external consumer, which should use `runKopularApp`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kopular",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.2",
|
|
4
4
|
"description": "Kopular: a small component framework for KopScript — components, reactive state, constructor-injected services, routing, real compiled templates, and HTTP, with no DI container",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@types/jsdom": "^30.0.0",
|
|
63
63
|
"@types/node": "^20.14.0",
|
|
64
64
|
"jsdom": "^25.0.1",
|
|
65
|
-
"kopscript": "^0.
|
|
65
|
+
"kopscript": "^0.24.0",
|
|
66
66
|
"typescript": "^5.5.0",
|
|
67
67
|
"vitest": "^4.1.11"
|
|
68
68
|
},
|
package/src/testing.js
CHANGED
|
@@ -39,13 +39,25 @@ const OWN_SRC_DIR = dirname(fileURLToPath(import.meta.url));
|
|
|
39
39
|
// than anything wrong with the copied files themselves.
|
|
40
40
|
const TEMP_ROOT = join(OWN_SRC_DIR, "..", ".kopular-testing-tmp");
|
|
41
41
|
|
|
42
|
-
// Copies every .ks/.html file from `srcDir` into `dir`, plus any
|
|
43
|
-
// listed in `extraFiles`
|
|
44
|
-
//
|
|
45
|
-
//
|
|
42
|
+
// Copies every .ks/.html/.js file from `srcDir` into `dir`, plus any
|
|
43
|
+
// filename listed in `extraFiles` for anything with a different extension.
|
|
44
|
+
// `.js` is included alongside `.ks`/`.html` (not just left to `extraFiles`)
|
|
45
|
+
// because a hand-written, not-compiled-from-`.ks` companion file is a
|
|
46
|
+
// real, documented pattern now, not a one-off — most commonly a dynamic-
|
|
47
|
+
// `import()` loader shim for `Router.AddLazyRoute` (see kopscript's own
|
|
48
|
+
// LLM.md/README.md "extern" section, and Kopular's own "Lazy routes"
|
|
49
|
+
// docs), reached via a RELATIVE `extern ... from "./whatever";` the test
|
|
50
|
+
// author can't always know the exact filename of in advance — unlike
|
|
51
|
+
// http_runtime.js (a fixed name Kopular itself ships and controls, still
|
|
52
|
+
// the right fit for `extraFiles`), an app's own loader shim can be named
|
|
53
|
+
// anything. Any pre-existing `.js` with the same name as a `.ks` file
|
|
54
|
+
// gets harmlessly overwritten moments later by that `.ks`'s own fresh
|
|
55
|
+
// compiled output — copying it first only matters for a `.js` with no
|
|
56
|
+
// `.ks` counterpart at all, which is exactly the hand-written case this
|
|
57
|
+
// exists for.
|
|
46
58
|
function copySources(srcDir, dir, extraFiles) {
|
|
47
59
|
for (const name of readdirSync(srcDir)) {
|
|
48
|
-
if (name.endsWith(".ks") || name.endsWith(".html") || extraFiles.includes(name)) {
|
|
60
|
+
if (name.endsWith(".ks") || name.endsWith(".html") || name.endsWith(".js") || extraFiles.includes(name)) {
|
|
49
61
|
cpSync(join(srcDir, name), join(dir, name));
|
|
50
62
|
}
|
|
51
63
|
}
|
|
@@ -155,8 +167,9 @@ async function compileAndRun(dir, entryFileName, options) {
|
|
|
155
167
|
* installed `kopular` package into a temp node_modules/, for an entry
|
|
156
168
|
* that consumes Kopular via `extern ... from "kopular/..."` rather than
|
|
157
169
|
* relative `using`. Default false.
|
|
158
|
-
* @param {string[]} [options.extraFiles] - extra filenames
|
|
159
|
-
*
|
|
170
|
+
* @param {string[]} [options.extraFiles] - extra filenames to copy from
|
|
171
|
+
* srcDir beyond .ks/.html/.js (which are always copied), for anything
|
|
172
|
+
* with a different extension.
|
|
160
173
|
* @param {(...args: unknown[]) => unknown} [options.fetchMock] - replaces
|
|
161
174
|
* the global `fetch` for the duration of the run, for testing `Http`.
|
|
162
175
|
* @param {string} [options.url] - the jsdom document's URL. Default
|