@arkstack/inertia 0.15.5 → 0.16.1

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 CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Response } from "@arkstack/http";
2
- import { ViewFactory } from "@arkstack/view";
3
2
 
4
3
  //#region src/types.d.ts
5
4
  /**
@@ -11,8 +10,8 @@ import { ViewFactory } from "@arkstack/view";
11
10
  type PageProps = Record<string, unknown>;
12
11
  /**
13
12
  * The page object Inertia exchanges with the client. It is serialized to JSON for
14
- * Inertia XHR visits and embedded in the root template's `data-page` attribute on
15
- * the initial full-page visit.
13
+ * Inertia XHR visits and embedded in the root template's `data-page` script
14
+ * element on the initial full-page visit.
16
15
  *
17
16
  * @see https://inertiajs.com/the-protocol
18
17
  */
@@ -38,13 +37,13 @@ interface InertiaPage {
38
37
  interface InertiaConfig {
39
38
  /**
40
39
  * The root Edge template that wraps the SPA and renders the `data-page`
41
- * element. Defaults to `app`. When the view does not exist a minimal
42
- * built-in template is used.
40
+ * script element and mount div. Defaults to `app`. When the view does not
41
+ * exist a minimal built-in template is used.
43
42
  */
44
43
  root_view: string;
45
44
  /**
46
- * The id of the root DOM element the client mounts onto (the element that
47
- * carries the `data-page` attribute). Defaults to `app`.
45
+ * The id of the root DOM element the client mounts onto (and the `data-page`
46
+ * value on the JSON script element). Defaults to `app`.
48
47
  */
49
48
  root_id: string;
50
49
  /**
@@ -248,8 +247,15 @@ declare const resolveProps: (component: string, props: PageProps, request: Inert
248
247
  /** Escape a string for safe inclusion in a double-quoted HTML attribute. */
249
248
  declare const escapeHtmlAttribute: (value: string) => string;
250
249
  /**
251
- * Build the root mount element carrying the serialized page object in its
252
- * `data-page` attribute the element the Inertia client adapter hydrates.
250
+ * Build the elements the Inertia client adapter hydrates: the (empty) mount
251
+ * `<div id="…">` plus the JSON `<script type="application/json" data-page="…">`
252
+ * carrying the serialized page object.
253
+ *
254
+ * The client reads the initial page from the JSON script element
255
+ * (`script[data-page][type="application/json"]`), not from a `data-page`
256
+ * attribute on the mount div. Forward slashes are escaped to `\/` so an embedded
257
+ * `</script>` in the page payload cannot terminate the script element early
258
+ * (`\/` remains a valid JSON escape for `/`).
253
259
  */
254
260
  declare const renderDataPage: (page: InertiaPage, rootId: string) => string;
255
261
  /** Minimal built-in root document used when the configured root view is absent. */
@@ -265,23 +271,6 @@ declare const builtInTemplate: (mount: string, head?: string) => string;
265
271
  */
266
272
  declare const renderRootHtml: (page: InertiaPage, config: InertiaConfig) => Promise<string>;
267
273
  //#endregion
268
- //#region src/tags.d.ts
269
- /**
270
- * Register the `@inertia` and `@inertiaHead` Edge tags on a view factory.
271
- *
272
- * - `@inertia` renders the root mount element (`<div data-page="…">`), or the
273
- * server-rendered markup when SSR is enabled.
274
- * - `@inertiaHead` renders the SSR head tags (empty without SSR).
275
- *
276
- * Both read the values the adapter passes to the root template, so they replace
277
- * the equivalent `{{{ inertia }}}` / `{{{ inertiaHead }}}` interpolations.
278
- * Idempotent per factory.
279
- *
280
- * @param factory
281
- * @returns
282
- */
283
- declare const registerInertiaTags: (factory: ViewFactory) => void;
284
- //#endregion
285
274
  //#region src/ssr.d.ts
286
275
  /** The default address the Inertia SSR server listens on. */
287
276
  declare const DEFAULT_SSR_URL = "http://127.0.0.1:13714/render";
@@ -289,7 +278,7 @@ declare const DEFAULT_SSR_URL = "http://127.0.0.1:13714/render";
289
278
  interface SsrResponse {
290
279
  /** HTML strings to inject into the document `<head>` (title, meta, style). */
291
280
  head: string[];
292
- /** The rendered `<div id="app" data-page="…">…</div>` mount element. */
281
+ /** The rendered mount markup (JSON `<script data-page>` + server-rendered `<div>`). */
293
282
  body: string;
294
283
  }
295
284
  /**
@@ -392,4 +381,4 @@ declare const SEE_OTHER_METHODS: Set<string>;
392
381
  */
393
382
  declare const shouldUpgradeRedirect: (method: string, status: number) => boolean;
394
383
  //#endregion
395
- export { AlwaysProp, type AlwaysPropContract, DEFAULT_SSR_BUNDLE, DEFAULT_SSR_URL, DeferProp, type DeferPropContract, Inertia, type InertiaConfig, type InertiaPage, type InertiaPropWrapper, type InertiaRequest, type InertiaStore, LazyProp, type LazyPropContract, type PageProps, SEE_OTHER_METHODS, type SsrProcessController, type SsrResponse, type SuperviseOptions, builtInTemplate, configure, currentStore, defaultConfig, escapeHtmlAttribute, flushShared, inertia, inertiaConfig, isAlwaysProp, isDeferProp, isLazyProp, isPropWrapper, registerInertiaTags, renderDataPage, renderRootHtml, renderViaSsr, resetConfig, resolveProps, resolveSsrBundle, resolveVersion, runInertia, setVersion, shareData, sharedData, shouldUpgradeRedirect, superviseProcess };
384
+ export { AlwaysProp, type AlwaysPropContract, DEFAULT_SSR_BUNDLE, DEFAULT_SSR_URL, DeferProp, type DeferPropContract, Inertia, type InertiaConfig, type InertiaPage, type InertiaPropWrapper, type InertiaRequest, type InertiaStore, LazyProp, type LazyPropContract, type PageProps, SEE_OTHER_METHODS, type SsrProcessController, type SsrResponse, type SuperviseOptions, builtInTemplate, configure, currentStore, defaultConfig, escapeHtmlAttribute, flushShared, inertia, inertiaConfig, isAlwaysProp, isDeferProp, isLazyProp, isPropWrapper, renderDataPage, renderRootHtml, renderViaSsr, resetConfig, resolveProps, resolveSsrBundle, resolveVersion, runInertia, setVersion, shareData, sharedData, shouldUpgradeRedirect, superviseProcess };
package/dist/index.js CHANGED
@@ -1,18 +1,6 @@
1
1
  import { a as defaultConfig, c as resolveVersion, i as configure, l as setVersion, n as resolveSsrBundle, o as inertiaConfig, r as superviseProcess, s as resetConfig, t as DEFAULT_SSR_BUNDLE } from "./ssr-process-Cz4b8S_f.js";
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
3
  import { Response } from "@arkstack/http";
4
- //#region \0rolldown/runtime.js
5
- var __defProp = Object.defineProperty;
6
- var __exportAll = (all, no_symbols) => {
7
- let target = {};
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true
11
- });
12
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
13
- return target;
14
- };
15
- //#endregion
16
4
  //#region src/props.ts
17
5
  /**
18
6
  * A prop that is excluded from the initial page load and only resolved when the
@@ -160,11 +148,18 @@ const escapeHtmlAttribute = (value) => {
160
148
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
161
149
  };
162
150
  /**
163
- * Build the root mount element carrying the serialized page object in its
164
- * `data-page` attribute the element the Inertia client adapter hydrates.
151
+ * Build the elements the Inertia client adapter hydrates: the (empty) mount
152
+ * `<div id="…">` plus the JSON `<script type="application/json" data-page="…">`
153
+ * carrying the serialized page object.
154
+ *
155
+ * The client reads the initial page from the JSON script element
156
+ * (`script[data-page][type="application/json"]`), not from a `data-page`
157
+ * attribute on the mount div. Forward slashes are escaped to `\/` so an embedded
158
+ * `<\/script>` in the page payload cannot terminate the script element early
159
+ * (`\/` remains a valid JSON escape for `/`).
165
160
  */
166
161
  const renderDataPage = (page, rootId) => {
167
- return `<div id="${rootId}" data-page="${escapeHtmlAttribute(JSON.stringify(page))}"></div>`;
162
+ return `<script data-page="${rootId}" type="application/json">${JSON.stringify(page).replace(/\//g, "\\/")}<\/script><div id="${rootId}"></div>`;
168
163
  };
169
164
  /** Minimal built-in root document used when the configured root view is absent. */
170
165
  const builtInTemplate = (mount, head = "") => {
@@ -203,7 +198,7 @@ const renderRootHtml = async (page, config) => {
203
198
  }
204
199
  try {
205
200
  const { view } = await import("@arkstack/view");
206
- const { registerInertiaTags } = await Promise.resolve().then(() => tags_exports);
201
+ const { registerInertiaTags } = await import("./tags-C-fCNM8D.js");
207
202
  const factory = view();
208
203
  registerInertiaTags(factory);
209
204
  if (factory.exists(config.root_view)) return await view(config.root_view, {
@@ -313,6 +308,8 @@ var Inertia = class Inertia {
313
308
  const request = Inertia.request();
314
309
  const config = inertiaConfig();
315
310
  const version = await resolveVersion();
311
+ const appName = globalThis.config?.("app.name");
312
+ if (appName !== void 0 && Inertia.shared().appName === void 0) Inertia.share("appName", appName);
316
313
  if (isInertiaRequest(request) && request.method === "GET" && (request.header("x-inertia-version") ?? "") !== version) return Inertia.conflict(request.url);
317
314
  const { props: resolved, deferredProps } = await resolveProps(component, {
318
315
  ...sharedData(),
@@ -406,42 +403,4 @@ function inertia(component, props = {}) {
406
403
  return Inertia.render(component, props);
407
404
  }
408
405
  //#endregion
409
- //#region src/tags.ts
410
- var tags_exports = /* @__PURE__ */ __exportAll({ registerInertiaTags: () => registerInertiaTags });
411
- /** Factories that already have the Inertia tags registered. */
412
- const registered = /* @__PURE__ */ new WeakSet();
413
- /**
414
- * Build an Edge tag compiler that outputs a template data variable raw (falling
415
- * back to an empty string when it is absent).
416
- *
417
- * @param name
418
- * @returns
419
- */
420
- const outputVariable = (name) => {
421
- return (parser, buffer, token) => {
422
- const ast = parser.utils.transformAst(parser.utils.generateAST(`${name} || ""`, token.loc, token.filename), token.filename, parser);
423
- buffer.outputExpression(parser.utils.stringify(ast), token.filename, token.loc.start.line, false);
424
- };
425
- };
426
- /**
427
- * Register the `@inertia` and `@inertiaHead` Edge tags on a view factory.
428
- *
429
- * - `@inertia` renders the root mount element (`<div data-page="…">`), or the
430
- * server-rendered markup when SSR is enabled.
431
- * - `@inertiaHead` renders the SSR head tags (empty without SSR).
432
- *
433
- * Both read the values the adapter passes to the root template, so they replace
434
- * the equivalent `{{{ inertia }}}` / `{{{ inertiaHead }}}` interpolations.
435
- * Idempotent per factory.
436
- *
437
- * @param factory
438
- * @returns
439
- */
440
- const registerInertiaTags = (factory) => {
441
- if (registered.has(factory)) return;
442
- registered.add(factory);
443
- factory.tag("inertia", false, false, outputVariable("inertia"));
444
- factory.tag("inertiaHead", false, false, outputVariable("inertiaHead"));
445
- };
446
- //#endregion
447
- export { AlwaysProp, DEFAULT_SSR_BUNDLE, DEFAULT_SSR_URL, DeferProp, Inertia, LazyProp, SEE_OTHER_METHODS, builtInTemplate, configure, currentStore, defaultConfig, escapeHtmlAttribute, flushShared, inertia, inertiaConfig, isAlwaysProp, isDeferProp, isLazyProp, isPropWrapper, registerInertiaTags, renderDataPage, renderRootHtml, renderViaSsr, resetConfig, resolveProps, resolveSsrBundle, resolveVersion, runInertia, setVersion, shareData, sharedData, shouldUpgradeRedirect, superviseProcess };
406
+ export { AlwaysProp, DEFAULT_SSR_BUNDLE, DEFAULT_SSR_URL, DeferProp, Inertia, LazyProp, SEE_OTHER_METHODS, builtInTemplate, configure, currentStore, defaultConfig, escapeHtmlAttribute, flushShared, inertia, inertiaConfig, isAlwaysProp, isDeferProp, isLazyProp, isPropWrapper, renderDataPage, renderRootHtml, renderViaSsr, resetConfig, resolveProps, resolveSsrBundle, resolveVersion, runInertia, setVersion, shareData, sharedData, shouldUpgradeRedirect, superviseProcess };
package/dist/setup.js CHANGED
@@ -16,6 +16,9 @@ Publisher.publishes({
16
16
  entries: [{
17
17
  from: join(root, "stubs/config/inertia.ts.stub"),
18
18
  to: "src/config/inertia.ts"
19
+ }, {
20
+ from: join(root, "stubs/config/app.css.stub"),
21
+ to: "resources/css/app.css"
19
22
  }]
20
23
  });
21
24
  Publisher.publishes({
@@ -26,5 +29,98 @@ Publisher.publishes({
26
29
  to: "src/resources/views/app.edge"
27
30
  }]
28
31
  });
32
+ Publisher.publishes({
33
+ package: "@arkstack/inertia",
34
+ tag: "inertia-react",
35
+ entries: [
36
+ {
37
+ from: join(root, "stubs/react/resources/js/app.tsx.stub"),
38
+ to: "resources/js/app.tsx"
39
+ },
40
+ {
41
+ from: join(root, "stubs/react/vite.config.ts.stub"),
42
+ to: "vite.config.ts"
43
+ },
44
+ {
45
+ from: join(root, "stubs/react/resources/js/Pages/Index.tsx.stub"),
46
+ to: "resources/js/Pages/Index.tsx"
47
+ },
48
+ {
49
+ from: join(root, "stubs/shared/resources/js/vite-env.d.ts.stub"),
50
+ to: "resources/js/vite-env.d.ts"
51
+ }
52
+ ]
53
+ });
54
+ Publisher.publishes({
55
+ package: "@arkstack/inertia",
56
+ tag: "inertia-svelte",
57
+ entries: [
58
+ {
59
+ from: join(root, "stubs/svelte/resources/js/app.ts.stub"),
60
+ to: "resources/js/app.ts"
61
+ },
62
+ {
63
+ from: join(root, "stubs/svelte/vite.config.ts.stub"),
64
+ to: "vite.config.ts"
65
+ },
66
+ {
67
+ from: join(root, "stubs/svelte/resources/js/Pages/Index.svelte.stub"),
68
+ to: "resources/js/Pages/Index.svelte"
69
+ },
70
+ {
71
+ from: join(root, "stubs/shared/resources/js/vite-env.d.ts.stub"),
72
+ to: "resources/js/vite-env.d.ts"
73
+ }
74
+ ]
75
+ });
76
+ Publisher.publishes({
77
+ package: "@arkstack/inertia",
78
+ tag: "inertia-vue",
79
+ entries: [
80
+ {
81
+ from: join(root, "stubs/vue/resources/js/app.ts.stub"),
82
+ to: "resources/js/app.ts"
83
+ },
84
+ {
85
+ from: join(root, "stubs/vue/vite.config.ts.stub"),
86
+ to: "vite.config.ts"
87
+ },
88
+ {
89
+ from: join(root, "stubs/vue/resources/js/Pages/Index.vue.stub"),
90
+ to: "resources/js/Pages/Index.vue"
91
+ },
92
+ {
93
+ from: join(root, "stubs/shared/resources/js/vite-env.d.ts.stub"),
94
+ to: "resources/js/vite-env.d.ts"
95
+ }
96
+ ]
97
+ });
98
+ Publisher.confirm({
99
+ package: "@arkstack/inertia",
100
+ message: "What front-end framework are you using with Inertia?",
101
+ options: [
102
+ {
103
+ name: "React",
104
+ value: "inertia-react"
105
+ },
106
+ {
107
+ name: "Svelte",
108
+ value: "inertia-svelte"
109
+ },
110
+ {
111
+ name: "Vue",
112
+ value: "inertia-vue"
113
+ }
114
+ ],
115
+ callback: (tag, stub) => {
116
+ const exts = {
117
+ "inertia-react": "tsx",
118
+ "inertia-svelte": "ts",
119
+ "inertia-vue": "ts"
120
+ };
121
+ const reactRefresh = tag === "inertia-react" ? "@viteReactRefresh\n " : "";
122
+ return stub.replaceAll("{{ext}}", exts[tag] ?? "ts").replaceAll("{{reactRefresh}}", reactRefresh);
123
+ }
124
+ });
29
125
  //#endregion
30
126
  export {};
@@ -0,0 +1,38 @@
1
+ //#region src/tags.ts
2
+ /** Factories that already have the Inertia tags registered. */
3
+ const registered = /* @__PURE__ */ new WeakSet();
4
+ /**
5
+ * Build an Edge tag compiler that outputs a template data variable raw (falling
6
+ * back to an empty string when it is absent).
7
+ *
8
+ * @param name
9
+ * @returns
10
+ */
11
+ const outputVariable = (name) => {
12
+ return (parser, buffer, token) => {
13
+ const ast = parser.utils.transformAst(parser.utils.generateAST(`${name} || ""`, token.loc, token.filename), token.filename, parser);
14
+ buffer.outputExpression(parser.utils.stringify(ast), token.filename, token.loc.start.line, false);
15
+ };
16
+ };
17
+ /**
18
+ * Register the `@inertia` and `@inertiaHead` Edge tags on a view factory.
19
+ *
20
+ * - `@inertia` renders the root mount element (the JSON `<script data-page="…">`
21
+ * plus the mount `<div>`), or the server-rendered markup when SSR is enabled.
22
+ * - `@inertiaHead` renders the SSR head tags (empty without SSR).
23
+ *
24
+ * Both read the values the adapter passes to the root template, so they replace
25
+ * the equivalent `{{{ inertia }}}` / `{{{ inertiaHead }}}` interpolations.
26
+ * Idempotent per factory.
27
+ *
28
+ * @param factory
29
+ * @returns
30
+ */
31
+ const registerInertiaTags = (factory) => {
32
+ if (registered.has(factory)) return;
33
+ registered.add(factory);
34
+ factory.tag("inertia", false, false, outputVariable("inertia"));
35
+ factory.tag("inertiaHead", false, false, outputVariable("inertiaHead"));
36
+ };
37
+ //#endregion
38
+ export { registerInertiaTags };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/inertia",
3
- "version": "0.15.5",
3
+ "version": "0.16.1",
4
4
  "type": "module",
5
5
  "description": "InertiaJS server-side adapter for Arkstack, building the modern monolith with server-driven SPAs.",
6
6
  "homepage": "https://arkstack.toneflix.net/guide/inertia",
@@ -33,13 +33,13 @@
33
33
  "./package.json": "./package.json"
34
34
  },
35
35
  "dependencies": {
36
- "@arkstack/common": "^0.15.5"
36
+ "@arkstack/common": "^0.16.1"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@h3ravel/musket": "^2.2.1",
40
- "@arkstack/contract": "^0.15.5",
41
- "@arkstack/view": "^0.15.5",
42
- "@arkstack/http": "^0.15.5"
40
+ "@arkstack/contract": "^0.16.1",
41
+ "@arkstack/http": "^0.16.1",
42
+ "@arkstack/view": "^0.16.1"
43
43
  },
44
44
  "peerDependenciesMeta": {
45
45
  "@arkstack/view": {
@@ -0,0 +1,343 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ margin: 0;
6
+ padding: 0;
7
+ }
8
+
9
+ /* ── Dark theme (default) ── */
10
+ :root {
11
+ --gold-light: #f0c040;
12
+ --gold-mid: #c9960c;
13
+ --gold-dark: #8a6400;
14
+ --bg: #0b0c0e;
15
+ --bg-card: #111317;
16
+ --bg-snippet: #0d0f12;
17
+ --border: rgba(201, 150, 12, 0.18);
18
+ --text: #f5f0e8;
19
+ --muted: #7a7567;
20
+ --radius: 10px;
21
+ --card-hover: #161820;
22
+ --kw: #8a9ad6;
23
+ --fn: #e8c56a;
24
+ --str: #88c99a;
25
+ --cm: #4a5060;
26
+ --code-base: #d4b86a;
27
+ }
28
+
29
+ /* ── Light theme ── */
30
+ [data-theme="light"] {
31
+ --gold-light: #a06800;
32
+ --gold-mid: #8a5a00;
33
+ --gold-dark: #6b4400;
34
+ --bg: #f5f3ef;
35
+ --bg-card: #ffffff;
36
+ --bg-snippet: #f0ede8;
37
+ --border: rgba(160, 104, 0, 0.16);
38
+ --text: #1a1714;
39
+ --muted: #9a9080;
40
+ --card-hover: #f9f7f3;
41
+ --kw: #5460a0;
42
+ --fn: #8a6000;
43
+ --str: #2e7d52;
44
+ --cm: #aaa090;
45
+ --code-base: #7a5c20;
46
+ }
47
+
48
+ /* ── OS preference fallback (no JS) ── */
49
+ @media (prefers-color-scheme: light) {
50
+ :root:not([data-theme="dark"]) {
51
+ --gold-light: #a06800;
52
+ --gold-mid: #8a5a00;
53
+ --gold-dark: #6b4400;
54
+ --bg: #f5f3ef;
55
+ --bg-card: #ffffff;
56
+ --bg-snippet: #f0ede8;
57
+ --border: rgba(160, 104, 0, 0.16);
58
+ --text: #1a1714;
59
+ --muted: #9a9080;
60
+ --card-hover: #f9f7f3;
61
+ --kw: #5460a0;
62
+ --fn: #8a6000;
63
+ --str: #2e7d52;
64
+ --cm: #aaa090;
65
+ --code-base: #7a5c20;
66
+ }
67
+ }
68
+
69
+ html,
70
+ body {
71
+ min-height: 100vh;
72
+ background: var(--bg);
73
+ color: var(--text);
74
+ font-family: 'DM Mono', monospace;
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ padding: 2rem 1rem;
79
+ transition: background 0.25s, color 0.25s;
80
+ }
81
+
82
+ .page {
83
+ max-width: 580px;
84
+ width: 100%;
85
+ display: flex;
86
+ flex-direction: column;
87
+ align-items: center;
88
+ }
89
+
90
+ /* ── Top bar ── */
91
+ .topbar {
92
+ width: 100%;
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: space-between;
96
+ margin-bottom: 2.8rem;
97
+ }
98
+
99
+ /* ── Brand block ── */
100
+ .brand {
101
+ display: flex;
102
+ align-items: center;
103
+ gap: 18px;
104
+ }
105
+
106
+ .logo-wrap {
107
+ position: relative;
108
+ flex-shrink: 0;
109
+ }
110
+
111
+ .logo-wrap img {
112
+ width: 55px;
113
+ height: 55px;
114
+ display: block;
115
+ filter: drop-shadow(0 0 18px rgba(201, 150, 12, 0.35));
116
+ animation: floatLogo 4s ease-in-out infinite;
117
+ }
118
+
119
+ .halo {
120
+ position: absolute;
121
+ inset: -14px;
122
+ border-radius: 50%;
123
+ background: radial-gradient(circle, rgba(201, 150, 12, 0.1) 0%, transparent 70%);
124
+ pointer-events: none;
125
+ animation: pulse 4s ease-in-out infinite;
126
+ }
127
+
128
+ @keyframes floatLogo {
129
+
130
+ 0%,
131
+ 100% {
132
+ transform: translateY(0);
133
+ }
134
+
135
+ 50% {
136
+ transform: translateY(-5px);
137
+ }
138
+ }
139
+
140
+ @keyframes pulse {
141
+
142
+ 0%,
143
+ 100% {
144
+ opacity: 0.5;
145
+ transform: scale(1);
146
+ }
147
+
148
+ 50% {
149
+ opacity: 1;
150
+ transform: scale(1.08);
151
+ }
152
+ }
153
+
154
+ .brand-text {
155
+ display: flex;
156
+ flex-direction: column;
157
+ gap: 4px;
158
+ }
159
+
160
+ .wordmark {
161
+ font-family: 'Syne', sans-serif;
162
+ font-size: 2.5rem;
163
+ font-weight: 800;
164
+ letter-spacing: -0.03em;
165
+ color: var(--text);
166
+ line-height: 1;
167
+ }
168
+
169
+ .wordmark span {
170
+ color: var(--gold-light);
171
+ }
172
+
173
+ .tagline {
174
+ font-size: 0.75rem;
175
+ letter-spacing: 0.14em;
176
+ text-transform: uppercase;
177
+ color: var(--muted);
178
+ line-height: 1;
179
+ }
180
+
181
+ /* ── Status pill ── */
182
+ .status-row {
183
+ display: flex;
184
+ align-items: center;
185
+ gap: 8px;
186
+ background: rgba(201, 150, 12, 0.06);
187
+ border: 1px solid var(--border);
188
+ border-radius: 100px;
189
+ padding: 6px 16px 6px 10px;
190
+ font-size: 0.72rem;
191
+ letter-spacing: 0.06em;
192
+ color: var(--gold-light);
193
+ margin-top: 1rem;
194
+ margin-bottom: 2.8rem;
195
+ transition: border-color 0.25s;
196
+ }
197
+
198
+ .dot {
199
+ width: 7px;
200
+ height: 7px;
201
+ border-radius: 50%;
202
+ background: #4caf74;
203
+ box-shadow: 0 0 6px #4caf74;
204
+ animation: blink 2s ease-in-out infinite;
205
+ }
206
+
207
+ @keyframes blink {
208
+
209
+ 0%,
210
+ 100% {
211
+ opacity: 1;
212
+ }
213
+
214
+ 50% {
215
+ opacity: 0.4;
216
+ }
217
+ }
218
+
219
+ /* ── Divider ── */
220
+ .divider {
221
+ width: 100%;
222
+ height: 1px;
223
+ background: linear-gradient(90deg, transparent, var(--border), transparent);
224
+ margin-bottom: 2.8rem;
225
+ }
226
+
227
+ /* ── Feature cards ── */
228
+ .cards {
229
+ width: 100%;
230
+ display: grid;
231
+ grid-template-columns: 1fr 1fr 1fr;
232
+ gap: 12px;
233
+ margin-bottom: 2.4rem;
234
+ }
235
+
236
+ .card {
237
+ background: var(--bg-card);
238
+ border: 1px solid var(--border);
239
+ border-radius: var(--radius);
240
+ padding: 1.1rem 1rem;
241
+ display: flex;
242
+ flex-direction: column;
243
+ gap: 6px;
244
+ transition: border-color 0.2s, background 0.2s;
245
+ }
246
+
247
+ .card:hover {
248
+ border-color: var(--gold-mid);
249
+ background: var(--card-hover);
250
+ }
251
+
252
+ .card-icon {
253
+ font-size: 1.1rem;
254
+ margin-bottom: 4px;
255
+ opacity: 0.85;
256
+ width: 20px;
257
+ }
258
+
259
+ .card-title {
260
+ font-family: 'Syne', sans-serif;
261
+ font-weight: 700;
262
+ font-size: 0.82rem;
263
+ color: var(--text);
264
+ }
265
+
266
+ .card-desc {
267
+ font-size: 0.68rem;
268
+ color: var(--muted);
269
+ line-height: 1.5;
270
+ }
271
+
272
+ /* ── Code snippet ── */
273
+ .snippet {
274
+ width: 100%;
275
+ background: var(--bg-snippet);
276
+ border: 1px solid var(--border);
277
+ border-radius: var(--radius);
278
+ padding: 1.1rem 1.25rem;
279
+ margin-bottom: 2.4rem;
280
+ position: relative;
281
+ overflow: hidden;
282
+ transition: background 0.25s, border-color 0.25s;
283
+ }
284
+
285
+ .snippet::before {
286
+ content: '';
287
+ position: absolute;
288
+ top: 0;
289
+ left: 0;
290
+ right: 0;
291
+ height: 2px;
292
+ background: linear-gradient(90deg, var(--gold-dark), var(--gold-light), var(--gold-dark));
293
+ }
294
+
295
+ .snippet-label {
296
+ font-size: 0.65rem;
297
+ letter-spacing: 0.12em;
298
+ text-transform: uppercase;
299
+ color: var(--muted);
300
+ margin-bottom: 0.7rem;
301
+ }
302
+
303
+ .snippet code {
304
+ font-family: 'DM Mono', monospace;
305
+ font-size: 0.78rem;
306
+ color: var(--code-base);
307
+ display: block;
308
+ line-height: 1.9;
309
+ }
310
+
311
+ .kw {
312
+ color: var(--kw);
313
+ }
314
+
315
+ .fn {
316
+ color: var(--fn);
317
+ }
318
+
319
+ .str {
320
+ color: var(--str);
321
+ }
322
+
323
+ .cm {
324
+ color: var(--cm);
325
+ }
326
+
327
+ /* ── Footer ── */
328
+ .footer {
329
+ font-size: 0.65rem;
330
+ color: var(--muted);
331
+ text-align: center;
332
+ letter-spacing: 0.06em;
333
+ line-height: 2;
334
+ }
335
+
336
+ .footer a {
337
+ color: var(--gold-mid);
338
+ text-decoration: none;
339
+ }
340
+
341
+ .footer a:hover {
342
+ color: var(--gold-light);
343
+ }
@@ -0,0 +1,120 @@
1
+ export default function Index({
2
+ message,
3
+ appName,
4
+ title,
5
+ }: {
6
+ appName: string;
7
+ title: string;
8
+ message: string;
9
+ }) {
10
+ const root = document.documentElement
11
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
12
+ root.setAttribute('data-theme', prefersDark ? 'dark' : 'light')
13
+
14
+ return (
15
+ <div className="page">
16
+ <div className="brand">
17
+ <div className="logo-wrap">
18
+ <div className="halo"></div>
19
+ <img
20
+ src="https://arkstack.toneflix.net/logo.png"
21
+ alt="Arkstack logo"
22
+ />
23
+ </div>
24
+ <div className="brand-text">
25
+ <h1 className="wordmark">
26
+ Ark<span>stack</span>
27
+ </h1>
28
+ <p className="tagline">
29
+ Node.js Framework &mdash; Runtime Agnostic
30
+ </p>
31
+ </div>
32
+ </div>
33
+
34
+ <div className="status-row">
35
+ <div className="dot"></div>
36
+ {message}
37
+ </div>
38
+
39
+ <div className="divider"></div>
40
+
41
+ <div className="cards">
42
+ <div className="card">
43
+ <div className="card-icon">
44
+ <svg
45
+ xmlns="http://www.w3.org/2000/svg"
46
+ viewBox="0 0 24 24"
47
+ fill="currentColor"
48
+ >
49
+ <path d="M13 10H20L11 23V14H4L13 1V10Z"></path>
50
+ </svg>
51
+ </div>
52
+ <div className="card-title">Fast by default</div>
53
+ <div className="card-desc">
54
+ Zero-bloat core. Ships only what you need.
55
+ </div>
56
+ </div>
57
+ <div className="card">
58
+ <div className="card-icon">
59
+ <svg
60
+ xmlns="http://www.w3.org/2000/svg"
61
+ viewBox="0 0 24 24"
62
+ fill="currentColor"
63
+ >
64
+ <path d="M13 18V20H19V22H13C11.8954 22 11 21.1046 11 20V18H8C5.79086 18 4 16.2091 4 14V10H20V14C20 16.2091 18.2091 18 16 18H13ZM16 6H19C19.5523 6 20 6.44772 20 7V9H4V7C4 6.44772 4.44772 6 5 6H8V2H10V6H14V2H16V6ZM12 14.5C12.5523 14.5 13 14.0523 13 13.5C13 12.9477 12.5523 12.5 12 12.5C11.4477 12.5 11 12.9477 11 13.5C11 14.0523 11.4477 14.5 12 14.5Z"></path>
65
+ </svg>
66
+ </div>
67
+ <div className="card-title">Adapters</div>
68
+ <div className="card-desc">
69
+ Express, Fastify, Hono, Koa — swap runtimes freely.
70
+ </div>
71
+ </div>
72
+ <div className="card">
73
+ <div className="card-icon">
74
+ <svg
75
+ xmlns="http://www.w3.org/2000/svg"
76
+ viewBox="0 0 24 24"
77
+ fill="currentColor"
78
+ >
79
+ <path d="M20.0833 10.4999L21.2854 11.2212C21.5221 11.3633 21.5989 11.6704 21.4569 11.9072C21.4146 11.9776 21.3557 12.0365 21.2854 12.0787L11.9999 17.6499L2.71451 12.0787C2.47772 11.9366 2.40093 11.6295 2.54301 11.3927C2.58523 11.3223 2.64413 11.2634 2.71451 11.2212L3.9166 10.4999L11.9999 15.3499L20.0833 10.4999ZM20.0833 15.1999L21.2854 15.9212C21.5221 16.0633 21.5989 16.3704 21.4569 16.6072C21.4146 16.6776 21.3557 16.7365 21.2854 16.7787L12.5144 22.0412C12.1977 22.2313 11.8021 22.2313 11.4854 22.0412L2.71451 16.7787C2.47772 16.6366 2.40093 16.3295 2.54301 16.0927C2.58523 16.0223 2.64413 15.9634 2.71451 15.9212L3.9166 15.1999L11.9999 20.0499L20.0833 15.1999ZM12.5144 1.30864L21.2854 6.5712C21.5221 6.71327 21.5989 7.0204 21.4569 7.25719C21.4146 7.32757 21.3557 7.38647 21.2854 7.42869L11.9999 12.9999L2.71451 7.42869C2.47772 7.28662 2.40093 6.97949 2.54301 6.7427C2.58523 6.67232 2.64413 6.61343 2.71451 6.5712L11.4854 1.30864C11.8021 1.11864 12.1977 1.11864 12.5144 1.30864Z"></path>
80
+ </svg>
81
+ </div>
82
+ <div className="card-title">Structured</div>
83
+ <div className="card-desc">Modular conventions for Node.js.</div>
84
+ </div>
85
+ </div>
86
+
87
+ <div className="snippet">
88
+ <div className="snippet-label">get started</div>
89
+
90
+ <code>
91
+ <span className="cm">// src/routes/api.ts</span>
92
+ <br />
93
+ <span className="kw">import</span> {'{ Router }'}{' '}
94
+ <span className="kw">from</span>{' '}
95
+ <span className="str">'@arkstack/driver-express'</span>
96
+ <br />
97
+ <br />
98
+ Router.<span className="fn">get</span>(
99
+ <span className="str">'/'</span>, () =&gt; {'{'}
100
+ <br />
101
+ &nbsp;&nbsp;<span className="kw">return</span> {'{'} status:{' '}
102
+ <span className="str">'ok'</span> {'}'}
103
+ <br />
104
+ {'}'})
105
+ </code>
106
+ </div>
107
+
108
+ <p className="footer">
109
+ <a href="https://arkstack.toneflix.net/">Docs</a>{' '}
110
+ &nbsp;&middot;&nbsp;
111
+ <a href="https://github.com/arkstack-hq/arkstack">GitHub</a>{' '}
112
+ &nbsp;&middot;&nbsp;
113
+ <a href="https://discord.gg/jmQybxKQ7R">Discord</a>
114
+ <br />
115
+ Arkstack &copy; {new Date().getFullYear()} &mdash; By Toneflix
116
+ Technologies
117
+ </p>
118
+ </div>
119
+ )
120
+ }
@@ -0,0 +1,14 @@
1
+ import { createInertiaApp } from '@inertiajs/react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import type { ComponentType } from 'react';
4
+
5
+ createInertiaApp({
6
+ resolve: (name) => {
7
+ const pages = import.meta.glob<{ default: ComponentType }>('./Pages/**/*.tsx', { eager: true });
8
+
9
+ return pages[`./Pages/${name}.tsx`];
10
+ },
11
+ setup({ el, App, props }) {
12
+ createRoot(el).render(<App {...props} />);
13
+ },
14
+ });
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react'
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ build: {
7
+ manifest: true,
8
+ outDir: 'public/build',
9
+ rolldownOptions: { input: 'resources/js/app.tsx' },
10
+ },
11
+ })
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,136 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte'
3
+
4
+ export let appName: string
5
+ export let title: string
6
+ export let message: string
7
+
8
+ const currentYear = new Date().getFullYear()
9
+
10
+ onMount(() => {
11
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
12
+
13
+ document.documentElement.setAttribute(
14
+ 'data-theme',
15
+ prefersDark ? 'dark' : 'light',
16
+ )
17
+ })
18
+ </script>
19
+
20
+ <div class="page">
21
+ <div class="brand">
22
+ <div class="logo-wrap">
23
+ <div class="halo"></div>
24
+
25
+ <img
26
+ src="https://arkstack.toneflix.net/logo.png"
27
+ alt="Arkstack logo"
28
+ />
29
+ </div>
30
+
31
+ <div class="brand-text">
32
+ <h1 class="wordmark">
33
+ Ark<span>stack</span>
34
+ </h1>
35
+
36
+ <p class="tagline">
37
+ Node.js Framework &mdash; Runtime Agnostic
38
+ </p>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="status-row">
43
+ <div class="dot"></div>
44
+ {message}
45
+ </div>
46
+
47
+ <div class="divider"></div>
48
+
49
+ <div class="cards">
50
+ <div class="card">
51
+ <div class="card-icon">
52
+ <svg
53
+ xmlns="http://www.w3.org/2000/svg"
54
+ viewBox="0 0 24 24"
55
+ fill="currentColor"
56
+ >
57
+ <path d="M13 10H20L11 23V14H4L13 1V10Z" />
58
+ </svg>
59
+ </div>
60
+
61
+ <div class="card-title">Fast by default</div>
62
+
63
+ <div class="card-desc">
64
+ Zero-bloat core. Ships only what you need.
65
+ </div>
66
+ </div>
67
+
68
+ <div class="card">
69
+ <div class="card-icon">
70
+ <svg
71
+ xmlns="http://www.w3.org/2000/svg"
72
+ viewBox="0 0 24 24"
73
+ fill="currentColor"
74
+ >
75
+ <path d="M13 18V20H19V22H13C11.8954 22 11 21.1046 11 20V18H8C5.79086 18 4 16.2091 4 14V10H20V14C20 16.2091 18.2091 18 16 18H13ZM16 6H19C19.5523 6 20 6.44772 20 7V9H4V7C4 6.44772 4.44772 6 5 6H8V2H10V6H14V2H16V6ZM12 14.5C12.5523 14.5 13 14.0523 13 13.5C13 12.9477 12.5523 12.5 12 12.5C11.4477 12.5 11 12.9477 11 13.5C11 14.0523 11.4477 14.5 12 14.5Z" />
76
+ </svg>
77
+ </div>
78
+
79
+ <div class="card-title">Adapters</div>
80
+
81
+ <div class="card-desc">
82
+ Express, Fastify, Hono, Koa — swap runtimes freely.
83
+ </div>
84
+ </div>
85
+
86
+ <div class="card">
87
+ <div class="card-icon">
88
+ <svg
89
+ xmlns="http://www.w3.org/2000/svg"
90
+ viewBox="0 0 24 24"
91
+ fill="currentColor"
92
+ >
93
+ <path d="M20.0833 10.4999L21.2854 11.2212C21.5221 11.3633 21.5989 11.6704 21.4569 11.9072C21.4146 11.9776 21.3557 12.0365 21.2854 12.0787L11.9999 17.6499L2.71451 12.0787C2.47772 11.9366 2.40093 11.6295 2.54301 11.3927C2.58523 11.3223 2.64413 11.2634 2.71451 11.2212L3.9166 10.4999L11.9999 15.3499L20.0833 10.4999ZM20.0833 15.1999L21.2854 15.9212C21.5221 16.0633 21.5989 16.3704 21.4569 16.6072C21.4146 16.6776 21.3557 16.7365 21.2854 16.7787L12.5144 22.0412C12.1977 22.2313 11.8021 22.2313 11.4854 22.0412L2.71451 16.7787C2.47772 16.6366 2.40093 16.3295 2.54301 16.0927C2.58523 16.0223 2.64413 15.9634 2.71451 15.9212L3.9166 15.1999L11.9999 20.0499L20.0833 15.1999ZM12.5144 1.30864L21.2854 6.5712C21.5221 6.71327 21.5989 7.0204 21.4569 7.25719C21.4146 7.32757 21.3557 7.38647 21.2854 7.42869L11.9999 12.9999L2.71451 7.42869C2.47772 7.28662 2.40093 6.97949 2.54301 6.7427C2.58523 6.67232 2.64413 6.61343 2.71451 6.5712L11.4854 1.30864C11.8021 1.11864 12.1977 1.11864 12.5144 1.30864Z" />
94
+ </svg>
95
+ </div>
96
+
97
+ <div class="card-title">Structured</div>
98
+
99
+ <div class="card-desc">
100
+ Modular conventions for Node.js.
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ <div class="snippet">
106
+ <div class="snippet-label">
107
+ get started
108
+ </div>
109
+
110
+ <code>
111
+ <span class="cm">// src/routes/api.ts</span>
112
+ <br />
113
+ <span class="kw">import</span> {'{ Router }'}
114
+ <span class="kw"> from </span>
115
+ <span class="str">'@arkstack/driver-express'</span>
116
+ <br />
117
+ <br />
118
+ Router.<span class="fn">get</span>(<span class="str">'/'</span>, () =&gt; {'{'}
119
+ <br />
120
+ &nbsp;&nbsp;<span class="kw">return</span> {'{'} status:
121
+ <span class="str">'ok'</span> {'}'}
122
+ <br />
123
+ {'}'})
124
+ </code>
125
+ </div>
126
+
127
+ <p class="footer">
128
+ <a href="https://arkstack.toneflix.net/">Docs</a>
129
+ &nbsp;&middot;&nbsp;
130
+ <a href="https://github.com/arkstack-hq/arkstack">GitHub</a>
131
+ &nbsp;&middot;&nbsp;
132
+ <a href="https://discord.gg/jmQybxKQ7R">Discord</a>
133
+ <br />
134
+ Arkstack &copy; {currentYear} &mdash; By Toneflix Technologies
135
+ </p>
136
+ </div>
@@ -0,0 +1,13 @@
1
+ import { createInertiaApp } from '@inertiajs/svelte'
2
+ import { mount } from 'svelte'
3
+
4
+ createInertiaApp({
5
+ resolve: (name) => {
6
+ const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true });
7
+
8
+ return pages[`./Pages/${name}.svelte`];
9
+ },
10
+ setup({ el, App, props }) {
11
+ mount(App, { target: el, props });
12
+ },
13
+ })
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'vite'
2
+ import { svelte } from '@sveltejs/vite-plugin-svelte'
3
+
4
+ export default defineConfig({
5
+ plugins: [svelte()],
6
+ build: {
7
+ manifest: true,
8
+ outDir: 'public/build',
9
+ rolldownOptions: { input: 'resources/js/app.ts' },
10
+ },
11
+ })
@@ -1,12 +1,27 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
+
3
4
  <head>
4
5
  <meta charset="utf-8">
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <title>
8
+ {appName} - {title}
9
+ </title>
10
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
11
+ <link
12
+ rel="preconnect"
13
+ href="https://fonts.gstatic.com"
14
+ crossOrigin="use-credentials"
15
+ />
16
+ <link
17
+ href="https://fonts.googleapis.com/css2?family=Syne:wght@400;700;800&family=DM+Mono:wght@400;500&display=swap"
18
+ rel="stylesheet"
19
+ />
6
20
  @inertiaHead
7
- @vite('resources/js/app.ts')
8
- </head>
21
+ {{reactRefresh}}@vite(['resources/js/app.{{ext}}', 'resources/css/app.css'])
22
+ </head>
9
23
  <body>
10
24
  @inertia
11
25
  </body>
26
+
12
27
  </html>
@@ -0,0 +1,146 @@
1
+ <script setup lang="ts">
2
+ import { onMounted } from 'vue'
3
+
4
+ defineProps<{
5
+ appName: string
6
+ title: string
7
+ message: string
8
+ }>()
9
+
10
+ onMounted(() => {
11
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
12
+
13
+ document.documentElement.setAttribute(
14
+ 'data-theme',
15
+ prefersDark ? 'dark' : 'light',
16
+ )
17
+ })
18
+
19
+ const currentYear = new Date().getFullYear()
20
+ </script>
21
+
22
+ <template>
23
+ <div class="page">
24
+ <div class="brand">
25
+ <div class="logo-wrap">
26
+ <div class="halo" />
27
+
28
+ <img
29
+ src="https://arkstack.toneflix.net/logo.png"
30
+ alt="Arkstack logo"
31
+ />
32
+ </div>
33
+
34
+ <div class="brand-text">
35
+ <h1 class="wordmark">
36
+ Ark<span>stack</span>
37
+ </h1>
38
+
39
+ <p class="tagline">
40
+ Node.js Framework &mdash; Runtime Agnostic
41
+ </p>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="status-row">
46
+ <div class="dot" />
47
+ {{ message }}
48
+ </div>
49
+
50
+ <div class="divider" />
51
+
52
+ <div class="cards">
53
+ <div class="card">
54
+ <div class="card-icon">
55
+ <svg
56
+ xmlns="http://www.w3.org/2000/svg"
57
+ viewBox="0 0 24 24"
58
+ fill="currentColor"
59
+ >
60
+ <path d="M13 10H20L11 23V14H4L13 1V10Z" />
61
+ </svg>
62
+ </div>
63
+
64
+ <div class="card-title">
65
+ Fast by default
66
+ </div>
67
+
68
+ <div class="card-desc">
69
+ Zero-bloat core. Ships only what you need.
70
+ </div>
71
+ </div>
72
+
73
+ <div class="card">
74
+ <div class="card-icon">
75
+ <svg
76
+ xmlns="http://www.w3.org/2000/svg"
77
+ viewBox="0 0 24 24"
78
+ fill="currentColor"
79
+ >
80
+ <path d="M13 18V20H19V22H13C11.8954 22 11 21.1046 11 20V18H8C5.79086 18 4 16.2091 4 14V10H20V14C20 16.2091 18.2091 18 16 18H13ZM16 6H19C19.5523 6 20 6.44772 20 7V9H4V7C4 6.44772 4.44772 6 5 6H8V2H10V6H14V2H16V6ZM12 14.5C12.5523 14.5 13 14.0523 13 13.5C13 12.9477 12.5523 12.5 12 12.5C11.4477 12.5 11 12.9477 11 13.5C11 14.0523 11.4477 14.5 12 14.5Z" />
81
+ </svg>
82
+ </div>
83
+
84
+ <div class="card-title">
85
+ Adapters
86
+ </div>
87
+
88
+ <div class="card-desc">
89
+ Express, Fastify, Hono, Koa — swap runtimes freely.
90
+ </div>
91
+ </div>
92
+
93
+ <div class="card">
94
+ <div class="card-icon">
95
+ <svg
96
+ xmlns="http://www.w3.org/2000/svg"
97
+ viewBox="0 0 24 24"
98
+ fill="currentColor"
99
+ >
100
+ <path d="M20.0833 10.4999L21.2854 11.2212C21.5221 11.3633 21.5989 11.6704 21.4569 11.9072C21.4146 11.9776 21.3557 12.0365 21.2854 12.0787L11.9999 17.6499L2.71451 12.0787C2.47772 11.9366 2.40093 11.6295 2.54301 11.3927C2.58523 11.3223 2.64413 11.2634 2.71451 11.2212L3.9166 10.4999L11.9999 15.3499L20.0833 10.4999ZM20.0833 15.1999L21.2854 15.9212C21.5221 16.0633 21.5989 16.3704 21.4569 16.6072C21.4146 16.6776 21.3557 16.7365 21.2854 16.7787L12.5144 22.0412C12.1977 22.2313 11.8021 22.2313 11.4854 22.0412L2.71451 16.7787C2.47772 16.6366 2.40093 16.3295 2.54301 16.0927C2.58523 16.0223 2.64413 15.9634 2.71451 15.9212L3.9166 15.1999L11.9999 20.0499L20.0833 15.1999ZM12.5144 1.30864L21.2854 6.5712C21.5221 6.71327 21.5989 7.0204 21.4569 7.25719C21.4146 7.32757 21.3557 7.38647 21.2854 7.42869L11.9999 12.9999L2.71451 7.42869C2.47772 7.28662 2.40093 6.97949 2.54301 6.7427C2.58523 6.67232 2.64413 6.61343 2.71451 6.5712L11.4854 1.30864C11.8021 1.11864 12.1977 1.11864 12.5144 1.30864Z" />
101
+ </svg>
102
+ </div>
103
+
104
+ <div class="card-title">
105
+ Structured
106
+ </div>
107
+
108
+ <div class="card-desc">
109
+ Modular conventions for Node.js.
110
+ </div>
111
+ </div>
112
+ </div>
113
+
114
+ <div class="snippet">
115
+ <div class="snippet-label">
116
+ get started
117
+ </div>
118
+
119
+ <code>
120
+ <span class="cm">// src/routes/api.ts</span>
121
+ <br />
122
+ <span class="kw">import</span> { Router }
123
+ <span class="kw"> from </span>
124
+ <span class="str">'@arkstack/driver-express'</span>
125
+ <br />
126
+ <br />
127
+ Router.<span class="fn">get</span>(<span class="str">'/'</span>, () =&gt; {
128
+ <br />
129
+ &nbsp;&nbsp;<span class="kw">return</span> { status:
130
+ <span class="str">'ok'</span> }
131
+ <br />
132
+ })
133
+ </code>
134
+ </div>
135
+
136
+ <p class="footer">
137
+ <a href="https://arkstack.toneflix.net/">Docs</a>
138
+ &nbsp;&middot;&nbsp;
139
+ <a href="https://github.com/arkstack-hq/arkstack">GitHub</a>
140
+ &nbsp;&middot;&nbsp;
141
+ <a href="https://discord.gg/jmQybxKQ7R">Discord</a>
142
+ <br />
143
+ Arkstack &copy; {{ currentYear }} &mdash; By Toneflix Technologies
144
+ </p>
145
+ </div>
146
+ </template>
@@ -0,0 +1,15 @@
1
+ import { createApp, h } from 'vue'
2
+ import { createInertiaApp } from '@inertiajs/vue3'
3
+
4
+ createInertiaApp({
5
+ resolve: (name) => {
6
+ const pages = import.meta.glob('./Pages/**/*.vue', { eager: true });
7
+
8
+ return pages[`./Pages/${name}.vue`];
9
+ },
10
+ setup({ el, App, props, plugin }) {
11
+ createApp({ render: () => h(App, props) })
12
+ .use(plugin)
13
+ .mount(el);
14
+ },
15
+ })
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ export default defineConfig({
5
+ plugins: [vue()],
6
+ build: {
7
+ manifest: true,
8
+ outDir: 'public/build',
9
+ rolldownOptions: { input: 'resources/js/app.ts' },
10
+ },
11
+ })