@absolutejs/absolute 0.20.0-beta.120 → 0.20.0-beta.122
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/CHANGELOG.md +21 -0
- package/changelog.json +37 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/angular/index.js +14 -2
- package/dist/angular/index.js.map +5 -4
- package/dist/angular/server.js +14 -2
- package/dist/angular/server.js.map +5 -4
- package/dist/build.js +15 -3
- package/dist/build.js.map +6 -5
- package/dist/cli/{add-kt4qx8sh.js → add-9sa7e3vd.js} +5 -5
- package/dist/cli/{androidEmulatorController-v6chbhem.js → androidEmulatorController-sj141e1c.js} +3 -3
- package/dist/cli/{androidNativeWatcher-mgqws6ag.js → androidNativeWatcher-dnp95nk2.js} +3 -3
- package/dist/cli/{api-xtq3zqfg.js → api-2hd8cahp.js} +1 -1
- package/dist/cli/{compile-5m830csy.js → compile-hywymh6y.js} +1 -1
- package/dist/cli/config/server.js +59 -9
- package/dist/cli/db-8wweexdp.js +1100 -0
- package/dist/cli/{dev-ww30tdrv.js → dev-pdefc9ac.js} +9 -9
- package/dist/cli/{emulatorDoctor-y2nqmaha.js → emulatorDoctor-gzarrsex.js} +2 -2
- package/dist/cli/{emulatorInstaller-3shdna4g.js → emulatorInstaller-pjw4ex6q.js} +3 -3
- package/dist/cli/{expoDevController-zz516pdd.js → expoDevController-weywa74d.js} +3 -3
- package/dist/cli/{generate-zy3d9bce.js → generate-069p0dk3.js} +4 -4
- package/dist/cli/{htmx-63kt9qj1.js → htmx-5wh1jh75.js} +2 -2
- package/dist/cli/{index-t84wxk1p.js → index-00wfffav.js} +50 -8
- package/dist/cli/{index-wtyg9cy0.js → index-1ys3dnrs.js} +1 -1
- package/dist/cli/{index-knt92dm8.js → index-255xs63d.js} +1 -1
- package/dist/cli/{index-wspj2mq3.js → index-3x5wpx5d.js} +1 -1
- package/dist/cli/{index-28nxv57v.js → index-5cgsrv62.js} +12 -2
- package/dist/cli/{index-mxmg15c5.js → index-ddakkws4.js} +2 -2
- package/dist/cli/{index-ce870r79.js → index-erngp7a9.js} +1 -1
- package/dist/cli/{index-pa3hmzj7.js → index-j2nw3edf.js} +1 -1
- package/dist/cli/{index-1wgc9e0v.js → index-keg69zm1.js} +1 -1
- package/dist/cli/{index-5268nwjx.js → index-q3sq287p.js} +1 -1
- package/dist/cli/{index-jf1f6npt.js → index-rqbk0b30.js} +1 -1
- package/dist/cli/{index-q1d4ns4n.js → index-v26ze17p.js} +1 -1
- package/dist/cli/{index-hneb973j.js → index-vkkqe08e.js} +2 -2
- package/dist/cli/index.js +23 -18
- package/dist/cli/{info-crpftzxh.js → info-d74dr585.js} +1 -1
- package/dist/cli/{iosNativeWatcher-8w1gawg4.js → iosNativeWatcher-kggp7j9a.js} +4 -4
- package/dist/cli/{iosSimulatorController-5vhqvhg6.js → iosSimulatorController-xcxxfkzx.js} +4 -4
- package/dist/cli/{mobile-21vsmrjd.js → mobile-00bqw12c.js} +9 -9
- package/dist/cli/{ps-ha7bhpc6.js → ps-8y28kzmb.js} +1 -1
- package/dist/cli/{psTui-rxszyyz8.js → psTui-8e96mwgz.js} +1 -1
- package/dist/cli/{remoteMacProtocol-dybpgazw.js → remoteMacProtocol-r38jhg44.js} +4 -4
- package/dist/cli/{remove-pwfv4wsd.js → remove-3fd1z2hx.js} +4 -4
- package/dist/cli/{start-3bhf56tj.js → start-q08avhxg.js} +2 -2
- package/dist/cli/{typecheck-7n5599tp.js → typecheck-yj9s13eb.js} +1 -1
- package/dist/cli/{workspace-h7czpaqh.js → workspace-e3jt4as8.js} +1 -1
- package/dist/client/chunks/index-dk743xs6.js +146 -0
- package/dist/client/chunks/index-dk743xs6.js.map +10 -0
- package/dist/client/chunks/index-jrcwp722.js +12 -0
- package/dist/client/chunks/index-jrcwp722.js.map +10 -0
- package/dist/client/chunks/{islands-xj2n8nwf.js → islands-50dg63j9.js} +6 -3
- package/dist/client/chunks/{islands-xj2n8nwf.js.map → islands-50dg63j9.js.map} +3 -3
- package/dist/client/chunks/{react-pdg4325x.js → react-yq4ss9y4.js} +4 -3
- package/dist/client/chunks/{react-pdg4325x.js.map → react-yq4ss9y4.js.map} +2 -2
- package/dist/client/index.js +5 -4
- package/dist/client/index.js.map +2 -2
- package/dist/index.js +15 -3
- package/dist/index.js.map +6 -5
- package/dist/islands/index.js +14 -2
- package/dist/islands/index.js.map +5 -4
- package/dist/mobile/index.js +13 -3
- package/dist/mobile/index.js.map +4 -4
- package/dist/mobile/remoteMacAgentEntry.js +162 -162
- package/dist/react/index.js +14 -2
- package/dist/react/index.js.map +5 -4
- package/dist/react/server.js +14 -2
- package/dist/react/server.js.map +5 -4
- package/dist/src/cli/scripts/db.d.ts +2 -19
- package/dist/src/cli/scripts/dbEngines/detect.d.ts +8 -0
- package/dist/src/cli/scripts/dbEngines/mssql.d.ts +4 -0
- package/dist/src/cli/scripts/dbEngines/mysql.d.ts +2 -0
- package/dist/src/cli/scripts/dbEngines/open.d.ts +2 -0
- package/dist/src/cli/scripts/dbEngines/postgres.d.ts +2 -0
- package/dist/src/cli/scripts/dbEngines/sqlText.d.ts +13 -0
- package/dist/src/cli/scripts/dbEngines/sqlite.d.ts +4 -0
- package/dist/src/cli/scripts/dbEngines/values.d.ts +12 -0
- package/dist/src/cli/utils.d.ts +7 -0
- package/dist/src/client/browserTranslation.d.ts +3 -0
- package/dist/src/client/browserTranslationAttributes.d.ts +2 -0
- package/dist/src/utils/userAgentFunctions.d.ts +1 -1
- package/dist/src/vue/components/Image.d.ts +1 -1
- package/dist/svelte/index.js +14 -2
- package/dist/svelte/index.js.map +5 -4
- package/dist/svelte/server.js +14 -2
- package/dist/svelte/server.js.map +5 -4
- package/dist/types/db.d.ts +109 -0
- package/dist/vue/browser.js +75 -8
- package/dist/vue/browser.js.map +5 -4
- package/dist/vue/index.js +77 -9
- package/dist/vue/index.js.map +6 -5
- package/dist/vue/server.js +14 -2
- package/dist/vue/server.js.map +5 -4
- package/package.json +13 -1
- package/dist/cli/db-tejnwt9j.js +0 -238
- package/dist/client/chunks/index-5py90ctf.js +0 -87
- package/dist/client/chunks/index-5py90ctf.js.map +0 -10
package/dist/cli/db-tejnwt9j.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
colors
|
|
4
|
-
} from "./index-8nym68py.js";
|
|
5
|
-
import {
|
|
6
|
-
UNFOUND_INDEX
|
|
7
|
-
} from "./index-czwrxgdj.js";
|
|
8
|
-
import"./index-mywsk201.js";
|
|
9
|
-
|
|
10
|
-
// src/cli/scripts/db.ts
|
|
11
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
12
|
-
import { join } from "path";
|
|
13
|
-
var {env, spawn, SQL } = globalThis.Bun;
|
|
14
|
-
var BACKUP_FORMAT_VERSION = 1;
|
|
15
|
-
var RESTORE_CHUNK_ROWS = 500;
|
|
16
|
-
var URL_ENV_KEYS = ["DATABASE_URL", "POSTGRES_URL", "DATABASE_URL_UNPOOLED"];
|
|
17
|
-
var JSON_DATA_TYPES = ["json", "jsonb"];
|
|
18
|
-
var SEED_CANDIDATES = ["db/seed.ts", "src/db/seed.ts", "seed.ts"];
|
|
19
|
-
var VALUE_FLAGS = ["--out", "--url", "--only", "--exclude"];
|
|
20
|
-
var paint = (text, color) => `${color}${text}${colors.reset}`;
|
|
21
|
-
var chunkRows = (items, size) => Array.from({ length: Math.ceil(items.length / size) }, (_, idx) => items.slice(idx * size, idx * size + size));
|
|
22
|
-
var quoteIdent = (name) => `"${name.replace(/"/g, '""')}"`;
|
|
23
|
-
var resolveUrl = (explicit) => {
|
|
24
|
-
const found = explicit ?? URL_ENV_KEYS.map((key) => env[key]).find((value) => typeof value === "string" && value !== "");
|
|
25
|
-
if (found === undefined || found === "")
|
|
26
|
-
throw new Error(`No database URL found. Set ${URL_ENV_KEYS.join(" or ")}, or pass --url <url>.`);
|
|
27
|
-
return found;
|
|
28
|
-
};
|
|
29
|
-
var keepTable = (name, options) => (options.only.length === 0 || options.only.includes(name)) && !options.exclude.includes(name);
|
|
30
|
-
var listTables = async (sql) => {
|
|
31
|
-
const rows = await sql`select table_name from information_schema.tables where table_schema = ${"public"} and table_type = ${"BASE TABLE"} order by table_name`;
|
|
32
|
-
return rows.map((row) => row.table_name);
|
|
33
|
-
};
|
|
34
|
-
var columnsFor = async (sql, name) => {
|
|
35
|
-
const rows = await sql.unsafe(`select column_name, data_type from information_schema.columns where table_schema = $1 and table_name = $2 order by ordinal_position`, ["public", name]);
|
|
36
|
-
return rows.map((row) => ({
|
|
37
|
-
isJson: JSON_DATA_TYPES.includes(row.data_type),
|
|
38
|
-
name: row.column_name
|
|
39
|
-
}));
|
|
40
|
-
};
|
|
41
|
-
var primaryKeyFor = async (sql, name) => {
|
|
42
|
-
const rows = await sql.unsafe(`select a.attname as col from pg_index i join pg_attribute a on a.attrelid = i.indrelid and a.attnum = any(i.indkey) where i.indrelid = $1::regclass and i.indisprimary order by a.attnum`, [`public.${quoteIdent(name)}`]);
|
|
43
|
-
return rows.map((row) => row.col);
|
|
44
|
-
};
|
|
45
|
-
var tableMeta = async (sql, name) => {
|
|
46
|
-
const [columns, primaryKey] = await Promise.all([
|
|
47
|
-
columnsFor(sql, name),
|
|
48
|
-
primaryKeyFor(sql, name)
|
|
49
|
-
]);
|
|
50
|
-
return { columns, name, primaryKey };
|
|
51
|
-
};
|
|
52
|
-
var foreignLinks = async (sql) => {
|
|
53
|
-
const rows = await sql.unsafe(`select tc.table_name as child, ccu.table_name as parent from information_schema.table_constraints tc join information_schema.constraint_column_usage ccu on ccu.constraint_name = tc.constraint_name and ccu.table_schema = tc.table_schema where tc.constraint_type = 'FOREIGN KEY' and tc.table_schema = $1`, ["public"]);
|
|
54
|
-
return rows.map((row) => ({
|
|
55
|
-
from: row.child,
|
|
56
|
-
to: row.parent
|
|
57
|
-
}));
|
|
58
|
-
};
|
|
59
|
-
var conflictClause = (meta) => {
|
|
60
|
-
if (meta.primaryKey.length === 0)
|
|
61
|
-
return "on conflict do nothing";
|
|
62
|
-
const target = meta.primaryKey.map(quoteIdent).join(", ");
|
|
63
|
-
const updatable = meta.columns.map((col) => col.name).filter((name) => !meta.primaryKey.includes(name));
|
|
64
|
-
if (updatable.length === 0)
|
|
65
|
-
return `on conflict (${target}) do nothing`;
|
|
66
|
-
const sets = updatable.map((name) => `${quoteIdent(name)} = excluded.${quoteIdent(name)}`).join(", ");
|
|
67
|
-
return `on conflict (${target}) do update set ${sets}`;
|
|
68
|
-
};
|
|
69
|
-
var dependencyOrder = (names, links) => {
|
|
70
|
-
const present = new Set(names);
|
|
71
|
-
const edges = links.filter((link) => present.has(link.from) && present.has(link.to) && link.from !== link.to);
|
|
72
|
-
const indegree = new Map(names.map((name) => [name, 0]));
|
|
73
|
-
edges.forEach((link) => indegree.set(link.from, (indegree.get(link.from) ?? 0) + 1));
|
|
74
|
-
const ready = names.filter((name) => (indegree.get(name) ?? 0) === 0);
|
|
75
|
-
const ordered = [];
|
|
76
|
-
const release = (parent) => edges.filter((link) => link.to === parent).forEach((link) => {
|
|
77
|
-
const next = (indegree.get(link.from) ?? 0) - 1;
|
|
78
|
-
indegree.set(link.from, next);
|
|
79
|
-
if (next === 0)
|
|
80
|
-
ready.push(link.from);
|
|
81
|
-
});
|
|
82
|
-
const drain = () => {
|
|
83
|
-
const head = ready.shift();
|
|
84
|
-
if (head === undefined)
|
|
85
|
-
return;
|
|
86
|
-
ordered.push(head);
|
|
87
|
-
release(head);
|
|
88
|
-
drain();
|
|
89
|
-
};
|
|
90
|
-
drain();
|
|
91
|
-
names.forEach((name) => {
|
|
92
|
-
if (!ordered.includes(name))
|
|
93
|
-
ordered.push(name);
|
|
94
|
-
});
|
|
95
|
-
return ordered;
|
|
96
|
-
};
|
|
97
|
-
var encodeValue = (col, value) => {
|
|
98
|
-
if (value === null || value === undefined)
|
|
99
|
-
return null;
|
|
100
|
-
if (col.isJson)
|
|
101
|
-
return JSON.stringify(value);
|
|
102
|
-
return value;
|
|
103
|
-
};
|
|
104
|
-
var insertChunk = async (sql, meta, rows) => {
|
|
105
|
-
const colNames = meta.columns.map((col) => col.name);
|
|
106
|
-
const groups = rows.map((_, rowIdx) => {
|
|
107
|
-
const base = rowIdx * colNames.length;
|
|
108
|
-
const slots = [...colNames.keys()].map((colIdx) => `$${base + colIdx + 1}`);
|
|
109
|
-
return `(${slots.join(", ")})`;
|
|
110
|
-
});
|
|
111
|
-
const params = rows.flatMap((row) => meta.columns.map((col) => encodeValue(col, row[col.name])));
|
|
112
|
-
const columnList = colNames.map(quoteIdent).join(", ");
|
|
113
|
-
const query = `insert into ${quoteIdent(meta.name)} (${columnList}) values ${groups.join(", ")} ${conflictClause(meta)}`;
|
|
114
|
-
await sql.unsafe(query, params);
|
|
115
|
-
};
|
|
116
|
-
var restoreTable = async (sql, meta, rows) => {
|
|
117
|
-
if (meta === undefined || rows.length === 0)
|
|
118
|
-
return;
|
|
119
|
-
await chunkRows(rows, RESTORE_CHUNK_ROWS).reduce(async (prev, part) => {
|
|
120
|
-
await prev;
|
|
121
|
-
return insertChunk(sql, meta, part);
|
|
122
|
-
}, Promise.resolve());
|
|
123
|
-
};
|
|
124
|
-
var truncateAll = async (sql, names) => {
|
|
125
|
-
if (names.length === 0)
|
|
126
|
-
return;
|
|
127
|
-
const list = names.map(quoteIdent).join(", ");
|
|
128
|
-
await sql.unsafe(`truncate ${list} restart identity cascade`);
|
|
129
|
-
};
|
|
130
|
-
var runBackup = async (options) => {
|
|
131
|
-
const sql = new SQL(options.url);
|
|
132
|
-
const chosen = (await listTables(sql)).filter((name) => keepTable(name, options));
|
|
133
|
-
const dumps = await Promise.all(chosen.map(async (name) => {
|
|
134
|
-
const rows = await sql.unsafe(`select * from ${quoteIdent(name)}`);
|
|
135
|
-
return [name, rows];
|
|
136
|
-
}));
|
|
137
|
-
await sql.end();
|
|
138
|
-
const tables = Object.fromEntries(dumps);
|
|
139
|
-
const payload = {
|
|
140
|
-
at: new Date().toISOString(),
|
|
141
|
-
tables,
|
|
142
|
-
v: BACKUP_FORMAT_VERSION
|
|
143
|
-
};
|
|
144
|
-
const dir = options.out ?? join(process.cwd(), "backups");
|
|
145
|
-
mkdirSync(dir, { recursive: true });
|
|
146
|
-
const json = JSON.stringify(payload, (_, value) => typeof value === "bigint" ? value.toString() : value);
|
|
147
|
-
const file = join(dir, `backup-${payload.at.replace(/[:.]/g, "-")}.json`);
|
|
148
|
-
writeFileSync(file, json);
|
|
149
|
-
writeFileSync(join(dir, "latest.json"), json);
|
|
150
|
-
const total = chosen.reduce((sum, name) => sum + (tables[name]?.length ?? 0), 0);
|
|
151
|
-
console.log(paint(`\u2713 backup \u2192 ${file}`, colors.green));
|
|
152
|
-
console.log(paint(` ${chosen.length} tables, ${total} rows`, colors.dim));
|
|
153
|
-
};
|
|
154
|
-
var runRestore = async (file, options) => {
|
|
155
|
-
if (!existsSync(file))
|
|
156
|
-
throw new Error(`Backup not found: ${file}`);
|
|
157
|
-
const payload = JSON.parse(readFileSync(file, "utf-8"));
|
|
158
|
-
const names = Object.keys(payload.tables).filter((name) => keepTable(name, options));
|
|
159
|
-
const sql = new SQL(options.url);
|
|
160
|
-
const order = dependencyOrder(names, await foreignLinks(sql));
|
|
161
|
-
const metas = await Promise.all(order.map((name) => tableMeta(sql, name)));
|
|
162
|
-
const metaByName = new Map(metas.map((meta) => [meta.name, meta]));
|
|
163
|
-
const aborted = options.truncate && !options.yes && prompt(paint(`\u26A0 TRUNCATE ${order.length} tables before restore? type "yes": `, colors.yellow)) !== "yes";
|
|
164
|
-
if (aborted) {
|
|
165
|
-
await sql.end();
|
|
166
|
-
console.log(paint("aborted", colors.yellow));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (options.truncate)
|
|
170
|
-
await truncateAll(sql, [...order].reverse());
|
|
171
|
-
await order.reduce(async (prev, name) => {
|
|
172
|
-
await prev;
|
|
173
|
-
return restoreTable(sql, metaByName.get(name), payload.tables[name] ?? []);
|
|
174
|
-
}, Promise.resolve());
|
|
175
|
-
await sql.end();
|
|
176
|
-
const total = order.reduce((sum, name) => sum + (payload.tables[name]?.length ?? 0), 0);
|
|
177
|
-
console.log(paint(`\u2713 restored ${order.length} tables, ${total} rows (idempotent upsert by primary key)`, colors.green));
|
|
178
|
-
};
|
|
179
|
-
var runSeed = async (entry) => {
|
|
180
|
-
const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync(join(process.cwd(), candidate)));
|
|
181
|
-
if (target === undefined)
|
|
182
|
-
throw new Error(`No seed script found (looked for ${SEED_CANDIDATES.join(", ")}). Pass a path: absolute db seed <file>.`);
|
|
183
|
-
console.log(paint(`seeding via ${target}\u2026`, colors.cyan));
|
|
184
|
-
const proc = spawn(["bun", "run", target], {
|
|
185
|
-
stderr: "inherit",
|
|
186
|
-
stdin: "inherit",
|
|
187
|
-
stdout: "inherit"
|
|
188
|
-
});
|
|
189
|
-
const code = await proc.exited;
|
|
190
|
-
if (code !== 0)
|
|
191
|
-
throw new Error(`Seed failed (exit ${code}).`);
|
|
192
|
-
};
|
|
193
|
-
var flagValue = (rest, flag) => {
|
|
194
|
-
const idx = rest.indexOf(flag);
|
|
195
|
-
return idx === UNFOUND_INDEX ? undefined : rest[idx + 1];
|
|
196
|
-
};
|
|
197
|
-
var listValue = (rest, flag) => (flagValue(rest, flag) ?? "").split(",").map((part) => part.trim()).filter((part) => part !== "");
|
|
198
|
-
var parseOptions = (rest) => ({
|
|
199
|
-
exclude: listValue(rest, "--exclude"),
|
|
200
|
-
only: listValue(rest, "--only"),
|
|
201
|
-
out: flagValue(rest, "--out"),
|
|
202
|
-
truncate: rest.includes("--truncate"),
|
|
203
|
-
url: resolveUrl(flagValue(rest, "--url")),
|
|
204
|
-
yes: rest.includes("--yes") || rest.includes("-y")
|
|
205
|
-
});
|
|
206
|
-
var positionalArgs = (rest) => rest.filter((arg, idx) => !arg.startsWith("-") && !VALUE_FLAGS.includes(rest[idx - 1] ?? ""));
|
|
207
|
-
var usage = () => {
|
|
208
|
-
console.error("Usage: absolute db <backup|restore|seed> [options]");
|
|
209
|
-
console.error(" backup [--out <dir>] [--only a,b] [--exclude a,b] [--url <url>] Dump tables \u2192 JSON (+ latest.json)");
|
|
210
|
-
console.error(" restore [file] [--truncate] [--only a,b] [--exclude a,b] [-y] Idempotent upsert by primary key");
|
|
211
|
-
console.error(" seed [file] Run the project\u2019s seed script");
|
|
212
|
-
process.exit(1);
|
|
213
|
-
};
|
|
214
|
-
var runDb = async (args) => {
|
|
215
|
-
const [sub, ...rest] = args;
|
|
216
|
-
if (sub === "backup") {
|
|
217
|
-
await runBackup(parseOptions(rest));
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
if (sub === "restore") {
|
|
221
|
-
const file = positionalArgs(rest)[0] ?? join(process.cwd(), "backups", "latest.json");
|
|
222
|
-
await runRestore(file, parseOptions(rest));
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
if (sub === "seed") {
|
|
226
|
-
await runSeed(positionalArgs(rest)[0]);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
usage();
|
|
230
|
-
};
|
|
231
|
-
export {
|
|
232
|
-
chunkRows,
|
|
233
|
-
conflictClause,
|
|
234
|
-
dependencyOrder,
|
|
235
|
-
encodeValue,
|
|
236
|
-
quoteIdent,
|
|
237
|
-
runDb
|
|
238
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// src/client/browserTranslation.ts
|
|
2
|
-
var translationRestorer = (restore, hasTranslation) => Object.assign(restore, { hasTranslation });
|
|
3
|
-
var emptyTranslationRestorer = () => translationRestorer(() => {
|
|
4
|
-
return;
|
|
5
|
-
}, false);
|
|
6
|
-
var textNodeAt = (parent, index) => {
|
|
7
|
-
const node = parent.childNodes[index];
|
|
8
|
-
return node instanceof Text ? node : undefined;
|
|
9
|
-
};
|
|
10
|
-
var visitElements = (root, visit) => {
|
|
11
|
-
visit(root);
|
|
12
|
-
for (const element of root.querySelectorAll("*"))
|
|
13
|
-
visit(element);
|
|
14
|
-
};
|
|
15
|
-
var elementPath = (root, element) => {
|
|
16
|
-
const path = [];
|
|
17
|
-
let current = element;
|
|
18
|
-
while (current !== root) {
|
|
19
|
-
const parent = current.parentElement;
|
|
20
|
-
if (parent === null)
|
|
21
|
-
return null;
|
|
22
|
-
path.unshift([...parent.children].indexOf(current));
|
|
23
|
-
current = parent;
|
|
24
|
-
}
|
|
25
|
-
return path;
|
|
26
|
-
};
|
|
27
|
-
var elementAtPath = (root, path) => {
|
|
28
|
-
let current = root;
|
|
29
|
-
for (const index of path) {
|
|
30
|
-
const child = current.children[index];
|
|
31
|
-
if (!(child instanceof Element))
|
|
32
|
-
return null;
|
|
33
|
-
current = child;
|
|
34
|
-
}
|
|
35
|
-
return current;
|
|
36
|
-
};
|
|
37
|
-
var captureSsrTextBaselines = (root) => {
|
|
38
|
-
if (root === null || typeof window === "undefined")
|
|
39
|
-
return;
|
|
40
|
-
const baselines = window.__ABSOLUTE_SSR_TEXT_BASELINES__ ?? new WeakMap;
|
|
41
|
-
visitElements(root, (element) => {
|
|
42
|
-
const text = new Map;
|
|
43
|
-
for (const [index, node] of [...element.childNodes].entries()) {
|
|
44
|
-
if (node.nodeType === Node.TEXT_NODE)
|
|
45
|
-
text.set(index, node.nodeValue ?? "");
|
|
46
|
-
}
|
|
47
|
-
if (text.size > 0)
|
|
48
|
-
baselines.set(element, text);
|
|
49
|
-
});
|
|
50
|
-
window.__ABSOLUTE_SSR_TEXT_BASELINES__ = baselines;
|
|
51
|
-
};
|
|
52
|
-
var prepareBrowserTranslationHydration = (root) => {
|
|
53
|
-
if (root === null || typeof window === "undefined")
|
|
54
|
-
return emptyTranslationRestorer();
|
|
55
|
-
const baselines = window.__ABSOLUTE_SSR_TEXT_BASELINES__;
|
|
56
|
-
if (baselines === undefined)
|
|
57
|
-
return emptyTranslationRestorer();
|
|
58
|
-
const translated = [];
|
|
59
|
-
visitElements(root, (element) => {
|
|
60
|
-
const text = baselines.get(element);
|
|
61
|
-
const path = elementPath(root, element);
|
|
62
|
-
if (text === undefined || path === null)
|
|
63
|
-
return;
|
|
64
|
-
for (const [index, baseline] of text) {
|
|
65
|
-
const node = textNodeAt(element, index);
|
|
66
|
-
if (node === undefined || node.data === baseline)
|
|
67
|
-
continue;
|
|
68
|
-
translated.push({ baseline, index, path, translated: node.data });
|
|
69
|
-
node.data = baseline;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
return translationRestorer(() => {
|
|
73
|
-
for (const snapshot of translated) {
|
|
74
|
-
const parent = elementAtPath(root, snapshot.path);
|
|
75
|
-
if (parent === null)
|
|
76
|
-
continue;
|
|
77
|
-
const node = textNodeAt(parent, snapshot.index);
|
|
78
|
-
if (node !== undefined && node.data === snapshot.baseline)
|
|
79
|
-
node.data = snapshot.translated;
|
|
80
|
-
}
|
|
81
|
-
}, translated.length > 0);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export { captureSsrTextBaselines, prepareBrowserTranslationHydration };
|
|
85
|
-
|
|
86
|
-
//# debugId=7A942374163F685B64756E2164756E21
|
|
87
|
-
//# sourceMappingURL=index-5py90ctf.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/client/browserTranslation.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"type TextBaseline = ReadonlyMap<number, string>;\ntype SsrTextBaselines = WeakMap<Element, TextBaseline>;\n\ndeclare global {\n\t// Window augmentation requires interface declaration merging.\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n\tinterface Window {\n\t\t__ABSOLUTE_SSR_TEXT_BASELINES__?: SsrTextBaselines;\n\t}\n}\n\ntype TranslatedText = {\n\tbaseline: string;\n\tindex: number;\n\tpath: number[];\n\ttranslated: string;\n};\n\nconst translationRestorer = (restore: () => void, hasTranslation: boolean) =>\n\tObject.assign(restore, { hasTranslation });\n\nconst emptyTranslationRestorer = () =>\n\ttranslationRestorer(() => undefined, false);\n\nconst textNodeAt = (parent: Element, index: number) => {\n\tconst node = parent.childNodes[index];\n\n\treturn node instanceof Text ? node : undefined;\n};\n\nconst visitElements = (root: Element, visit: (element: Element) => void) => {\n\tvisit(root);\n\tfor (const element of root.querySelectorAll('*')) visit(element);\n};\n\nconst elementPath = (root: Element, element: Element) => {\n\tconst path: number[] = [];\n\tlet current = element;\n\twhile (current !== root) {\n\t\tconst parent = current.parentElement;\n\t\tif (parent === null) return null;\n\t\tpath.unshift([...parent.children].indexOf(current));\n\t\tcurrent = parent;\n\t}\n\n\treturn path;\n};\n\nconst elementAtPath = (root: Element, path: number[]) => {\n\tlet current = root;\n\tfor (const index of path) {\n\t\tconst child = current.children[index];\n\t\tif (!(child instanceof Element)) return null;\n\t\tcurrent = child;\n\t}\n\n\treturn current;\n};\n\n/** Capture server-authored text before client modules load. Absolute page\n * handlers install the same snapshot inline; this export supports custom\n * documents and non-standard bootstraps. */\nexport const captureSsrTextBaselines = (root: Element | null) => {\n\tif (root === null || typeof window === 'undefined') return;\n\tconst baselines: SsrTextBaselines =\n\t\twindow.__ABSOLUTE_SSR_TEXT_BASELINES__ ?? new WeakMap();\n\tvisitElements(root, (element) => {\n\t\tconst text = new Map<number, string>();\n\t\tfor (const [index, node] of [...element.childNodes].entries()) {\n\t\t\tif (node.nodeType === Node.TEXT_NODE)\n\t\t\t\ttext.set(index, node.nodeValue ?? '');\n\t\t}\n\t\tif (text.size > 0) baselines.set(element, text);\n\t});\n\twindow.__ABSOLUTE_SSR_TEXT_BASELINES__ = baselines;\n};\n\n/** Temporarily restore server text while a framework attaches to SSR DOM,\n * then reapply translated text. Paths preserve translations even when a\n * framework replaces nodes while mounting. Genuine server/client mismatches\n * are left unchanged. */\nexport const prepareBrowserTranslationHydration = (root: Element | null) => {\n\tif (root === null || typeof window === 'undefined')\n\t\treturn emptyTranslationRestorer();\n\tconst baselines = window.__ABSOLUTE_SSR_TEXT_BASELINES__;\n\tif (baselines === undefined) return emptyTranslationRestorer();\n\tconst translated: TranslatedText[] = [];\n\tvisitElements(root, (element) => {\n\t\tconst text = baselines.get(element);\n\t\tconst path = elementPath(root, element);\n\t\tif (text === undefined || path === null) return;\n\t\tfor (const [index, baseline] of text) {\n\t\t\tconst node = textNodeAt(element, index);\n\t\t\tif (node === undefined || node.data === baseline) continue;\n\t\t\ttranslated.push({ baseline, index, path, translated: node.data });\n\t\t\tnode.data = baseline;\n\t\t}\n\t});\n\n\treturn translationRestorer(() => {\n\t\tfor (const snapshot of translated) {\n\t\t\tconst parent = elementAtPath(root, snapshot.path);\n\t\t\tif (parent === null) continue;\n\t\t\tconst node = textNodeAt(parent, snapshot.index);\n\t\t\tif (node !== undefined && node.data === snapshot.baseline)\n\t\t\t\tnode.data = snapshot.translated;\n\t\t}\n\t}, translated.length > 0);\n};\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "7A942374163F685B64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|