@ternkit/tern 0.4.0 → 1.0.0
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/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/runtime/router.svelte.js +12 -4
- package/dist/runtime/state.svelte.d.ts +11 -0
- package/dist/runtime/state.svelte.js +16 -0
- package/dist/runtime/types.d.ts +4 -0
- package/dist/vite/index.js +13 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* </script>
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
export { page, navigating } from './runtime/state.svelte.js';
|
|
10
|
+
export { page, navigating, env } from './runtime/state.svelte.js';
|
|
11
11
|
export { goto, invalidate, invalidateAll, preloadData, applyAction } from './runtime/router.svelte.js';
|
|
12
12
|
export { beforeNavigate, onNavigate, afterNavigate } from './runtime/navigation.js';
|
|
13
13
|
export type { BeforeNavigateEvent, OnNavigateEvent } from './runtime/navigation.js';
|
|
@@ -15,4 +15,4 @@ export { enhance } from './runtime/forms.js';
|
|
|
15
15
|
export type { SubmitFunction, SubmitInput, SubmitResult } from './runtime/forms.js';
|
|
16
16
|
export type { ActionResult, GotoOptions, Navigation, NavigationTarget, NavigationType } from './runtime/types.js';
|
|
17
17
|
/** The version of the Tern client runtime. */
|
|
18
|
-
export declare const VERSION = "0.
|
|
18
|
+
export declare const VERSION = "1.0.0";
|
package/dist/index.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* </script>
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
export { page, navigating } from './runtime/state.svelte.js';
|
|
10
|
+
export { page, navigating, env } from './runtime/state.svelte.js';
|
|
11
11
|
export { goto, invalidate, invalidateAll, preloadData, applyAction } from './runtime/router.svelte.js';
|
|
12
12
|
export { beforeNavigate, onNavigate, afterNavigate } from './runtime/navigation.js';
|
|
13
13
|
export { enhance } from './runtime/forms.js';
|
|
14
14
|
/** The version of the Tern client runtime. */
|
|
15
|
-
export const VERSION = '0.
|
|
15
|
+
export const VERSION = '1.0.0';
|
|
@@ -81,7 +81,7 @@ export async function goto(href, opts = {}) {
|
|
|
81
81
|
throw new Error('Tern: goto() was called before the app started');
|
|
82
82
|
}
|
|
83
83
|
const url = new URL(href, location.href);
|
|
84
|
-
if (url
|
|
84
|
+
if (!inApp(url)) {
|
|
85
85
|
location.href = url.href;
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
@@ -162,6 +162,7 @@ function setForm(form) {
|
|
|
162
162
|
}
|
|
163
163
|
function dataURL(url, reuse) {
|
|
164
164
|
const path = url.pathname.replace(/\/$/, '');
|
|
165
|
+
// The base path is part of the pathname; the server strips it.
|
|
165
166
|
let target = `${path}/__data.json${url.search}`;
|
|
166
167
|
if (reuse) {
|
|
167
168
|
const here = url.pathname + url.search;
|
|
@@ -240,7 +241,7 @@ async function navigate(url, opts, type, redirects, popIndex, fromIndex) {
|
|
|
240
241
|
}
|
|
241
242
|
if (payload.type === 'redirect' && payload.location) {
|
|
242
243
|
const next = new URL(payload.location, url);
|
|
243
|
-
if (redirects >= MAX_REDIRECTS || next
|
|
244
|
+
if (redirects >= MAX_REDIRECTS || !inApp(next)) {
|
|
244
245
|
location.href = next.href;
|
|
245
246
|
return;
|
|
246
247
|
}
|
|
@@ -410,12 +411,19 @@ function findAnchor(event) {
|
|
|
410
411
|
}
|
|
411
412
|
return null;
|
|
412
413
|
}
|
|
414
|
+
/** Reports whether url belongs to this app (its origin and base path). */
|
|
415
|
+
function inApp(url) {
|
|
416
|
+
if (url.origin !== location.origin)
|
|
417
|
+
return false;
|
|
418
|
+
const base = manifest.base ?? '';
|
|
419
|
+
return !base || url.pathname === base || url.pathname.startsWith(base + '/');
|
|
420
|
+
}
|
|
413
421
|
function anchorURL(a) {
|
|
414
422
|
const href = a instanceof SVGAElement ? a.href.baseVal : a.href;
|
|
415
423
|
if (!href)
|
|
416
424
|
return null;
|
|
417
425
|
const url = new URL(href, document.baseURI);
|
|
418
|
-
if (url
|
|
426
|
+
if (!inApp(url) || !/^https?:$/.test(url.protocol))
|
|
419
427
|
return null;
|
|
420
428
|
const target = a instanceof SVGAElement ? a.target.baseVal : a.target;
|
|
421
429
|
if (target && target !== '_self')
|
|
@@ -476,7 +484,7 @@ function listen() {
|
|
|
476
484
|
return;
|
|
477
485
|
}
|
|
478
486
|
const url = new URL(submitter?.hasAttribute('formaction') ? submitter.formAction : own.action);
|
|
479
|
-
if (url
|
|
487
|
+
if (!inApp(url))
|
|
480
488
|
return;
|
|
481
489
|
event.preventDefault();
|
|
482
490
|
url.search = new URLSearchParams(new FormData(form, submitter)).toString();
|
|
@@ -46,6 +46,17 @@ export declare const navigating: {
|
|
|
46
46
|
readonly current: Navigation | null;
|
|
47
47
|
};
|
|
48
48
|
export declare function setNavigating(n: Navigation | null): void;
|
|
49
|
+
/**
|
|
50
|
+
* The server's PUBLIC_ environment variables, read when it started:
|
|
51
|
+
*
|
|
52
|
+
* ```js
|
|
53
|
+
* import { env } from '@ternkit/tern';
|
|
54
|
+
* fetch(`${env.PUBLIC_API_URL}/status`);
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* Only variables whose names start with PUBLIC_ are sent to the browser.
|
|
58
|
+
*/
|
|
59
|
+
export declare const env: Record<string, string | undefined>;
|
|
49
60
|
/** Updates page state for a rendered payload. */
|
|
50
61
|
export declare function applyPayloadToPage(p: Payload, url: URL, state: Record<string, unknown>, data: Record<string, unknown>[]): void;
|
|
51
62
|
export {};
|
|
@@ -49,8 +49,24 @@ export const navigating = {
|
|
|
49
49
|
export function setNavigating(n) {
|
|
50
50
|
navigatingState.current = n;
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* The server's PUBLIC_ environment variables, read when it started:
|
|
54
|
+
*
|
|
55
|
+
* ```js
|
|
56
|
+
* import { env } from '@ternkit/tern';
|
|
57
|
+
* fetch(`${env.PUBLIC_API_URL}/status`);
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* Only variables whose names start with PUBLIC_ are sent to the browser.
|
|
61
|
+
*/
|
|
62
|
+
export const env = {};
|
|
52
63
|
/** Updates page state for a rendered payload. */
|
|
53
64
|
export function applyPayloadToPage(p, url, state, data) {
|
|
65
|
+
if (p.env) {
|
|
66
|
+
for (const k of Object.keys(env))
|
|
67
|
+
delete env[k];
|
|
68
|
+
Object.assign(env, p.env);
|
|
69
|
+
}
|
|
54
70
|
page.url = url;
|
|
55
71
|
page.params = p.params ?? {};
|
|
56
72
|
page.route = { id: p.route ?? null };
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface RouteEntry {
|
|
|
21
21
|
}
|
|
22
22
|
/** The client manifest generated by `tern gen` in .tern/generated/manifest.js. */
|
|
23
23
|
export interface ClientManifest {
|
|
24
|
+
/** The base path from tern.json, such as '/app', or ''. */
|
|
25
|
+
base?: string;
|
|
24
26
|
layouts: LayoutEntry[];
|
|
25
27
|
routes: Record<string, RouteEntry>;
|
|
26
28
|
fallback: {
|
|
@@ -47,6 +49,8 @@ export interface Payload {
|
|
|
47
49
|
uses?: (NodeUses | null)[];
|
|
48
50
|
/** Nodes the server skipped because the client already has their data. */
|
|
49
51
|
reused?: number[];
|
|
52
|
+
/** PUBLIC_ environment variables, on full page loads. */
|
|
53
|
+
env?: Record<string, string>;
|
|
50
54
|
}
|
|
51
55
|
export interface NodeUses {
|
|
52
56
|
url?: boolean;
|
package/dist/vite/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
2
|
+
import fs from 'node:fs';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
/** Paths shared with the Go code generator; keep in sync with internal/codegen. */
|
|
4
5
|
const CLIENT_ENTRY = '.tern/generated/client.js';
|
|
@@ -28,8 +29,10 @@ export function tern(options = {}) {
|
|
|
28
29
|
name: 'tern',
|
|
29
30
|
config(config, env) {
|
|
30
31
|
root = path.resolve(config.root ?? process.cwd());
|
|
32
|
+
const basePath = readBasePath(root);
|
|
31
33
|
const shared = {
|
|
32
34
|
appType: 'custom',
|
|
35
|
+
base: basePath + '/',
|
|
33
36
|
resolve: {
|
|
34
37
|
alias: {
|
|
35
38
|
$lib: path.join(root, 'src/lib'),
|
|
@@ -115,4 +118,14 @@ export function tern(options = {}) {
|
|
|
115
118
|
}
|
|
116
119
|
return [...svelte(options.svelte), plugin];
|
|
117
120
|
}
|
|
121
|
+
/** Reads basePath from tern.json; the Go side validates it. */
|
|
122
|
+
function readBasePath(root) {
|
|
123
|
+
try {
|
|
124
|
+
const config = JSON.parse(fs.readFileSync(path.join(root, 'tern.json'), 'utf8'));
|
|
125
|
+
return config.basePath ?? '';
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
118
131
|
export default tern;
|