@yourrealm/sdk 0.0.0-alpha.1378.ce03c8dc

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 (230) hide show
  1. package/LICENSE-EXCEPTION +26 -0
  2. package/README.md +34 -0
  3. package/dist/chunk-3R6KEFOI.js +22 -0
  4. package/dist/chunk-67BDAMYX.js +376 -0
  5. package/dist/chunk-AITGS27R.js +139 -0
  6. package/dist/chunk-CMAEHQ4F.js +6 -0
  7. package/dist/chunk-MLKGABMK.js +9 -0
  8. package/dist/chunk-O3UIK34B.js +1430 -0
  9. package/dist/chunk-VHTUSZUX.js +176 -0
  10. package/dist/cli.js +9006 -0
  11. package/dist/docker.js +54 -0
  12. package/dist/index.js +1053 -0
  13. package/dist/ingress.js +436 -0
  14. package/dist/jsx-runtime.js +2 -0
  15. package/dist/preact.js +22 -0
  16. package/dist/service-url.js +11 -0
  17. package/dist/services.js +213 -0
  18. package/dist/test.js +5069 -0
  19. package/dist/ui.js +254 -0
  20. package/dist/worker-protocol.js +89 -0
  21. package/package.json +112 -0
  22. package/src/app-icon.ts +74 -0
  23. package/src/apply.ts +52 -0
  24. package/src/bundle-ui.ts +211 -0
  25. package/src/bundle.ts +546 -0
  26. package/src/cli/build-dev-landing.ts +84 -0
  27. package/src/cli/build-install-panel.ts +90 -0
  28. package/src/cli/build-runtime.ts +133 -0
  29. package/src/cli/build.ts +63 -0
  30. package/src/cli/dev.ts +107 -0
  31. package/src/cli/down.ts +60 -0
  32. package/src/cli/main.ts +56 -0
  33. package/src/cli/test.ts +61 -0
  34. package/src/cli/validate.ts +37 -0
  35. package/src/compile.ts +100 -0
  36. package/src/create-app.ts +982 -0
  37. package/src/deep-merge.ts +33 -0
  38. package/src/dev/fixture.ts +48 -0
  39. package/src/dev/install-handler.ts +383 -0
  40. package/src/dev/server.ts +968 -0
  41. package/src/dev/stack.ts +108 -0
  42. package/src/dev/state.ts +159 -0
  43. package/src/docker.ts +96 -0
  44. package/src/errors.ts +61 -0
  45. package/src/factory.ts +481 -0
  46. package/src/garage.ts +56 -0
  47. package/src/generator/hash.ts +6 -0
  48. package/src/generator/resolve-refs.ts +207 -0
  49. package/src/grants-builder.ts +100 -0
  50. package/src/grants.ts +260 -0
  51. package/src/home-api.ts +172 -0
  52. package/src/home-cookie.ts +10 -0
  53. package/src/home-registry.ts +120 -0
  54. package/src/home.ts +187 -0
  55. package/src/host-registry.ts +143 -0
  56. package/src/http-header.ts +20 -0
  57. package/src/identifiers.ts +49 -0
  58. package/src/index.ts +66 -0
  59. package/src/info.ts +64 -0
  60. package/src/ini.ts +50 -0
  61. package/src/json.ts +14 -0
  62. package/src/jsx-runtime/index.ts +5 -0
  63. package/src/keys.ts +29 -0
  64. package/src/mysql.ts +56 -0
  65. package/src/pack-build.ts +108 -0
  66. package/src/pack.ts +115 -0
  67. package/src/peer-registry.ts +121 -0
  68. package/src/peer-world.ts +117 -0
  69. package/src/permission-meta.ts +116 -0
  70. package/src/permissions.ts +108 -0
  71. package/src/pkg-root.ts +34 -0
  72. package/src/postgres.ts +79 -0
  73. package/src/preact/index.ts +27 -0
  74. package/src/redis.ts +43 -0
  75. package/src/ref.ts +271 -0
  76. package/src/remote-registry.ts +33 -0
  77. package/src/required-host-kinds.ts +110 -0
  78. package/src/resolve-context.ts +111 -0
  79. package/src/resolve.ts +471 -0
  80. package/src/runtime/docker/compose/compose-schema.ts +118 -0
  81. package/src/runtime/docker/compose/convert-to-docker-compose.ts +278 -0
  82. package/src/runtime/docker/compose/default-hardening.ts +21 -0
  83. package/src/runtime/docker/compose/effects.ts +107 -0
  84. package/src/runtime/docker/compose/index.ts +17 -0
  85. package/src/runtime/docker/compose/labels.ts +39 -0
  86. package/src/runtime/docker/compose/types.ts +78 -0
  87. package/src/runtime/docker/home-proxy-server/index.ts +177 -0
  88. package/src/runtime/docker/home-proxy-server/protocol.ts +53 -0
  89. package/src/runtime/docker/ingress/build-config.ts +819 -0
  90. package/src/runtime/docker/ingress/index.ts +16 -0
  91. package/src/runtime/docker/ingress/types.ts +182 -0
  92. package/src/runtime/docker/log-frames.ts +121 -0
  93. package/src/runtime/docker/logs-server/index.ts +366 -0
  94. package/src/runtime/docker/spawn-server/context-key.ts +82 -0
  95. package/src/runtime/docker/spawn-server/index.ts +492 -0
  96. package/src/runtime/docker/spawn-server/protocol.ts +70 -0
  97. package/src/runtime/docker/spawn-server/spec.ts +122 -0
  98. package/src/runtime/docker/stats-server/disks.ts +161 -0
  99. package/src/runtime/docker/stats-server/index.ts +322 -0
  100. package/src/runtime/home-client/index.ts +71 -0
  101. package/src/runtime/log-line.ts +24 -0
  102. package/src/runtime/logs-client/index.ts +175 -0
  103. package/src/runtime/spawn-client/index.ts +93 -0
  104. package/src/runtime/spawn-client/kaniko.ts +79 -0
  105. package/src/runtime/stats-client/index.ts +65 -0
  106. package/src/runtime/stats-sample.ts +95 -0
  107. package/src/safe-json.ts +37 -0
  108. package/src/sandbox.ts +1209 -0
  109. package/src/schema/build-apps.ts +38 -0
  110. package/src/schema/home.ts +217 -0
  111. package/src/schema/host.ts +792 -0
  112. package/src/schema/inputs.ts +26 -0
  113. package/src/schema/nodes.ts +75 -0
  114. package/src/schema/peer.ts +400 -0
  115. package/src/schema/public-domain.ts +116 -0
  116. package/src/schema/remote.ts +74 -0
  117. package/src/security.ts +594 -0
  118. package/src/serialize.ts +21 -0
  119. package/src/service-definition.ts +284 -0
  120. package/src/service-url.ts +64 -0
  121. package/src/service.ts +39 -0
  122. package/src/services/index.ts +5 -0
  123. package/src/shared.ts +65 -0
  124. package/src/speculative-silo.ts +96 -0
  125. package/src/stable-secret.ts +14 -0
  126. package/src/surfaces.ts +264 -0
  127. package/src/tailwind-bin.ts +56 -0
  128. package/src/test/boot.ts +192 -0
  129. package/src/test/compile.ts +501 -0
  130. package/src/test/describe.ts +117 -0
  131. package/src/test/index.ts +11 -0
  132. package/src/test/ingress-fixture.ts +37 -0
  133. package/src/test/types.ts +318 -0
  134. package/src/trusted-headers.ts +79 -0
  135. package/src/types.ts +126 -0
  136. package/src/ui/components/aside.tsx +96 -0
  137. package/src/ui/components/badge.tsx +42 -0
  138. package/src/ui/components/button.tsx +59 -0
  139. package/src/ui/components/card.tsx +106 -0
  140. package/src/ui/components/checkbox.tsx +37 -0
  141. package/src/ui/components/code-block.tsx +29 -0
  142. package/src/ui/components/combobox.tsx +119 -0
  143. package/src/ui/components/config-field.tsx +284 -0
  144. package/src/ui/components/dialog.tsx +137 -0
  145. package/src/ui/components/domain-editor.tsx +317 -0
  146. package/src/ui/components/domain-list.ts +205 -0
  147. package/src/ui/components/dropdown-menu.tsx +73 -0
  148. package/src/ui/components/empty-state.tsx +51 -0
  149. package/src/ui/components/highlight.ts +59 -0
  150. package/src/ui/components/icons.tsx +101 -0
  151. package/src/ui/components/image-posture.tsx +85 -0
  152. package/src/ui/components/input.tsx +28 -0
  153. package/src/ui/components/label.tsx +16 -0
  154. package/src/ui/components/line-chart.tsx +113 -0
  155. package/src/ui/components/page.tsx +39 -0
  156. package/src/ui/components/permission-row.tsx +262 -0
  157. package/src/ui/components/permission-section.tsx +51 -0
  158. package/src/ui/components/pie-chart.tsx +245 -0
  159. package/src/ui/components/schema-block.tsx +60 -0
  160. package/src/ui/components/separator.tsx +42 -0
  161. package/src/ui/components/sheet.tsx +130 -0
  162. package/src/ui/components/sidebar.tsx +650 -0
  163. package/src/ui/components/silo-picker.tsx +510 -0
  164. package/src/ui/components/skeleton.tsx +13 -0
  165. package/src/ui/components/sonner.tsx +33 -0
  166. package/src/ui/components/switch.tsx +58 -0
  167. package/src/ui/components/table-view.ts +219 -0
  168. package/src/ui/components/table.tsx +506 -0
  169. package/src/ui/components/tabs.tsx +59 -0
  170. package/src/ui/components/timeago.tsx +84 -0
  171. package/src/ui/components/tooltip.tsx +56 -0
  172. package/src/ui/components.json +21 -0
  173. package/src/ui/dev/dev-shell.tsx +145 -0
  174. package/src/ui/home/home-grid.tsx +177 -0
  175. package/src/ui/hooks/use-mobile.ts +19 -0
  176. package/src/ui/index.ts +189 -0
  177. package/src/ui/install/adapter.ts +193 -0
  178. package/src/ui/install/deploy-targets-picker.tsx +185 -0
  179. package/src/ui/install/install-app-panel.tsx +912 -0
  180. package/src/ui/install/install-error.tsx +62 -0
  181. package/src/ui/install/perms-inactive.ts +50 -0
  182. package/src/ui/install/required-fields.ts +37 -0
  183. package/src/ui/install/tabs-form.tsx +557 -0
  184. package/src/ui/tokens.css +279 -0
  185. package/src/ui/utils.ts +78 -0
  186. package/src/ui-error.ts +139 -0
  187. package/src/ui-runtime/dev-landing-entry.tsx +258 -0
  188. package/src/ui-runtime/index.ts +83 -0
  189. package/src/ui-runtime/install-entry.tsx +119 -0
  190. package/src/ui-runtime/mount.ts +367 -0
  191. package/src/ui-runtime/runtime.css +56 -0
  192. package/src/ui-surface.ts +451 -0
  193. package/src/valkey.ts +43 -0
  194. package/src/worker/extract-tar.ts +125 -0
  195. package/src/worker/identity.ts +183 -0
  196. package/src/worker/index.ts +16 -0
  197. package/src/worker/public-ip.ts +92 -0
  198. package/src/worker/queue.ts +54 -0
  199. package/src/worker/reconcile.ts +127 -0
  200. package/src/worker/start-worker.ts +227 -0
  201. package/src/worker/ui-proxy.ts +335 -0
  202. package/src/worker/uplink.ts +523 -0
  203. package/src/worker/validate.ts +34 -0
  204. package/src/worker/verify-relay.ts +102 -0
  205. package/src/worker-protocol/app-dirs.ts +94 -0
  206. package/src/worker-protocol/home-proxy-paths.ts +76 -0
  207. package/src/worker-protocol/index.ts +55 -0
  208. package/src/worker-protocol/ingress.ts +166 -0
  209. package/src/worker-protocol/logs-socket-path.ts +50 -0
  210. package/src/worker-protocol/networks.ts +39 -0
  211. package/src/worker-protocol/node-version.ts +70 -0
  212. package/src/worker-protocol/silo-paths.ts +114 -0
  213. package/src/worker-protocol/spawn-paths.ts +165 -0
  214. package/src/worker-protocol/stats-socket-path.ts +40 -0
  215. package/src/worker-protocol/update-files.ts +77 -0
  216. package/src/worker-protocol/uplink/constants.ts +86 -0
  217. package/src/worker-protocol/uplink/errors.ts +61 -0
  218. package/src/worker-protocol/uplink/frame.ts +114 -0
  219. package/src/worker-protocol/uplink/identity.ts +40 -0
  220. package/src/worker-protocol/uplink/index.ts +63 -0
  221. package/src/worker-protocol/uplink/methods.ts +462 -0
  222. package/src/worker-protocol/uplink/mux.ts +646 -0
  223. package/src/worker-protocol/uplink/protocol.ts +11 -0
  224. package/src/worker-protocol/uplink/rpc.ts +309 -0
  225. package/src/worker-protocol/uplink/session.ts +540 -0
  226. package/src/worker-protocol/uplink/test-support.ts +188 -0
  227. package/src/worker-protocol/worker-mount.ts +27 -0
  228. package/src/worker-protocol/worker-state.ts +190 -0
  229. package/src/xml.ts +49 -0
  230. package/src/yaml.ts +15 -0
@@ -0,0 +1,219 @@
1
+ // The ordering and paging rules behind `<Table>`, with no JSX and no Preact in
2
+ // them, so `deno test` covers the comparison and the window math without a DOM.
3
+ //
4
+ // Both halves of the table story go through these functions. A hydrated caller
5
+ // runs them per render through `useTableView`; a plain Fresh route that never
6
+ // hydrates runs them on the server and renders links. Neither owns a rule the
7
+ // other doesn't have.
8
+
9
+ export type SortDirection = "asc" | "desc";
10
+ export type SortState = { key: string; direction: SortDirection };
11
+ export type SortValue = string | number | boolean | Date | null | undefined;
12
+
13
+ // One collator for the process, with the locale nailed down: SSR runs in Deno
14
+ // and hydration runs in the browser, so a comparison that reads the ambient
15
+ // locale can order the same rows two ways and print a hydration diff. `numeric`
16
+ // puts `app-2` before `app-10`; `sensitivity: "base"` stops `Zebra` sorting
17
+ // above `apple`. Constructed once - a collator costs about as much to build as
18
+ // the comparison it performs, and a sort calls this O(n log n) times.
19
+ const collator = new Intl.Collator("en", { numeric: true, sensitivity: "base" });
20
+
21
+ // "Nothing to compare", which is more than just `null`. An empty cell and a
22
+ // missing one read identically in the table, so they have to sort identically
23
+ // too, and a `NaN` that reached a numeric column is an absent measurement
24
+ // rather than a value smaller than every other one.
25
+ function isAbsent(value: SortValue): boolean {
26
+ return (
27
+ value === null ||
28
+ value === undefined ||
29
+ value === "" ||
30
+ (typeof value === "number" && Number.isNaN(value))
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Order two cell values ascending.
36
+ *
37
+ * Numbers, dates and booleans compare by value; everything else goes through
38
+ * the collator as a string. Sorting a number column as text is the classic
39
+ * table bug (`9` above `10`, `900 KiB` above `1 GiB`), so the accessors are
40
+ * expected to hand back raw values and the formatting stays in the cell.
41
+ *
42
+ * Absent values sort last here as well, so a direct caller gets the same
43
+ * answer, but {@link sortRows} does its own absent check before the direction
44
+ * flip - see there for why.
45
+ */
46
+ export function compareValues(a: SortValue, b: SortValue): number {
47
+ const aAbsent = isAbsent(a);
48
+ const bAbsent = isAbsent(b);
49
+ if (aAbsent || bAbsent) return aAbsent && bAbsent ? 0 : aAbsent ? 1 : -1;
50
+ // Dates fold into the numeric path rather than getting one of their own, so a
51
+ // column that yields `Date | number` still orders by value. The typeof guard
52
+ // keeps a mixed Date/string column out of it: `Number("a")` is NaN, a NaN
53
+ // comparator reads as 0 to `.sort`, and the result is not an order at all.
54
+ // Such a column falls through to the collator, which is at least total.
55
+ const av = a instanceof Date ? a.getTime() : a;
56
+ const bv = b instanceof Date ? b.getTime() : b;
57
+ if (typeof av === "number" && typeof bv === "number") return av - bv;
58
+ if (typeof av === "boolean" && typeof bv === "boolean") return Number(av) - Number(bv);
59
+ return collator.compare(String(av), String(bv));
60
+ }
61
+
62
+ /**
63
+ * A copy of `rows` ordered by one column, or `rows` itself when there is
64
+ * nothing to do.
65
+ *
66
+ * Three things this deliberately does not do:
67
+ *
68
+ * 1. It doesn't throw on a key it doesn't know. `sort` can arrive from a query
69
+ * string, where anyone can type anything, and a listing that 500s on a bad
70
+ * `?sort=` is worse than one that ignores it.
71
+ * 2. It doesn't flip absent values to the top on a descending sort. `null`,
72
+ * `undefined`, `""` and `NaN` sort last in BOTH directions, which is why the
73
+ * absent check sits outside the sign multiply. A descending sort that floats
74
+ * the empties up fills page 1 with the rows nobody paginated to see.
75
+ * 3. It doesn't sort in place. `[...rows].sort()` also buys stability, which
76
+ * has been spec-guaranteed since ES2019 and is what makes "sort by state,
77
+ * then click name" keep the first key as the tiebreaker.
78
+ */
79
+ export function sortRows<T>(
80
+ rows: readonly T[],
81
+ sort: SortState | null,
82
+ columns: Record<string, (row: T) => SortValue>,
83
+ ): readonly T[] {
84
+ if (!sort) return rows;
85
+ const accessor = columns[sort.key];
86
+ if (!accessor) return rows;
87
+ const sign = sort.direction === "desc" ? -1 : 1;
88
+ return [...rows].sort((x, y) => {
89
+ const a = accessor(x);
90
+ const b = accessor(y);
91
+ const aAbsent = isAbsent(a);
92
+ const bAbsent = isAbsent(b);
93
+ if (aAbsent || bAbsent) return aAbsent && bAbsent ? 0 : aAbsent ? 1 : -1;
94
+ return sign * compareValues(a, b);
95
+ });
96
+ }
97
+
98
+ /**
99
+ * What clicking a header does: the active column flips, any other column
100
+ * adopts its own `initial` direction.
101
+ *
102
+ * Carrying the current direction across to a new column is the wrong default -
103
+ * jumping from "newest first" to "targets, Z to A" is never what was meant.
104
+ * There is no third "unsorted" state on the way round: a table always has an
105
+ * order, and cycling back to the unsorted one just means an extra click to
106
+ * reach the direction you wanted.
107
+ */
108
+ export function toggleSort(
109
+ current: SortState | null,
110
+ key: string,
111
+ initial: SortDirection = "asc",
112
+ ): SortState {
113
+ if (current?.key === key) {
114
+ return { key, direction: current.direction === "asc" ? "desc" : "asc" };
115
+ }
116
+ return { key, direction: initial };
117
+ }
118
+
119
+ /**
120
+ * A `?sort=&dir=` pair off a URL, or null if it names nothing this table has.
121
+ *
122
+ * Strict on both halves: the key has to be in the allowlist and the direction
123
+ * has to be spelled exactly, so a hand-edited URL degrades to the default view
124
+ * instead of half-applying. A caller that wants a per-column default direction
125
+ * supplies it (`parseSort(key, dir ?? defaultDirFor(key), columns)`) rather
126
+ * than having one baked in here.
127
+ */
128
+ export function parseSort(
129
+ key: string | null | undefined,
130
+ direction: string | null | undefined,
131
+ columns: readonly string[],
132
+ ): SortState | null {
133
+ if (!key || !columns.includes(key)) return null;
134
+ if (direction !== "asc" && direction !== "desc") return null;
135
+ return { key, direction };
136
+ }
137
+
138
+ /**
139
+ * How many pages `total` rows fill.
140
+ *
141
+ * Never zero. Zero pages makes `clampPage` return 0 and the summary read "page
142
+ * 0 of 0"; an empty table is page 1 of 1, which is also the page the operator
143
+ * is looking at.
144
+ */
145
+ export function pageCount(total: number, pageSize: number): number {
146
+ if (!Number.isFinite(pageSize) || pageSize <= 0) return 1;
147
+ return Math.max(1, Math.ceil(Math.max(0, total) / pageSize));
148
+ }
149
+
150
+ /** The nearest page that exists. Junk (`NaN`, `-3`, `1e9`) snaps into range. */
151
+ export function clampPage(page: number, count: number): number {
152
+ const last = Math.max(1, Math.floor(count) || 1);
153
+ const wanted = Math.floor(page);
154
+ // NaN only. `Infinity` is junk too, but it is junk on the HIGH side, and
155
+ // `Math.min` already snaps it to the last page - bailing to 1 here would send
156
+ // "past the end" to the opposite end of the list from the one it asked for.
157
+ if (Number.isNaN(wanted) || wanted < 1) return 1;
158
+ return Math.min(wanted, last);
159
+ }
160
+
161
+ /** One page's worth of rows. A non-positive `pageSize` means "no paging". */
162
+ export function pageSlice<T>(rows: readonly T[], page: number, pageSize: number): readonly T[] {
163
+ if (!Number.isFinite(pageSize) || pageSize <= 0) return rows;
164
+ const current = clampPage(page, pageCount(rows.length, pageSize));
165
+ const start = (current - 1) * pageSize;
166
+ return rows.slice(start, start + pageSize);
167
+ }
168
+
169
+ /**
170
+ * The position line under the table.
171
+ *
172
+ * `to` is clamped at `total` so a partial last page can't claim rows that
173
+ * aren't there ("Showing 1,201-1,250 of 1,234"), and so is `from`, so a page
174
+ * number past the end still reads as a position rather than as arithmetic.
175
+ * Fixed locale, again because this string is rendered on both sides of
176
+ * hydration.
177
+ */
178
+ export function pageSummary(page: number, pageSize: number, total: number): string {
179
+ if (total <= 0) return "No results";
180
+ const n = (value: number) => value.toLocaleString("en-US");
181
+ const from = Math.min(Math.max(1, (page - 1) * pageSize + 1), total);
182
+ // Floored at `from` as well as capped at `total`: an unclamped page 0 would
183
+ // otherwise read "Showing 1-0 of 7", a range that runs backwards.
184
+ const to = Math.min(Math.max(page * pageSize, from), total);
185
+ return `Showing ${n(from)}-${n(to)} of ${n(total)}`;
186
+ }
187
+
188
+ /**
189
+ * The page numbers to render, with `"ellipsis"` standing in for the runs that
190
+ * are collapsed.
191
+ *
192
+ * The row is a **constant** width at a given `siblings` (`2 * siblings + 5`
193
+ * entries) for every page of a long list. A row that grows by two buttons the
194
+ * moment you leave page 1 slides the next button out from under the cursor
195
+ * between mousedown and click, which is a misclick the operator didn't make.
196
+ *
197
+ * The `left > 3` / `right < count - 2` guards are also what make an ellipsis
198
+ * standing in for a single page impossible, so there is no collapse fix-up
199
+ * pass: a gap is always at least two pages wide or it isn't a gap.
200
+ */
201
+ export function pageWindow(page: number, count: number, siblings = 1): (number | "ellipsis")[] {
202
+ const last = Math.max(1, Math.floor(count) || 1);
203
+ const current = clampPage(page, last);
204
+ // `siblings` is a public prop. A negative one makes the middle range run
205
+ // backwards, which drops the current page out of its own window.
206
+ const wings = Math.max(0, Math.floor(siblings) || 0);
207
+ const range = (from: number, to: number): number[] =>
208
+ Array.from({ length: to - from + 1 }, (_, i) => from + i);
209
+
210
+ // first + last + current + 2 * siblings + 2 ellipses.
211
+ const slots = wings * 2 + 5;
212
+ if (last <= slots) return range(1, last);
213
+
214
+ const showLeft = current - wings > 3;
215
+ const showRight = current + wings < last - 2;
216
+ if (!showLeft) return [...range(1, wings * 2 + 3), "ellipsis", last];
217
+ if (!showRight) return [1, "ellipsis", ...range(last - (wings * 2 + 2), last)];
218
+ return [1, "ellipsis", ...range(current - wings, current + wings), "ellipsis", last];
219
+ }