ryugi-artifacts 1.16.3 → 1.18.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/cli.cjs
CHANGED
package/dist/server.cjs
CHANGED
|
@@ -18585,11 +18585,18 @@ function agentAddOnBoard(value, specs) {
|
|
|
18585
18585
|
if (!spec) return { error: `no board ${v6.board}` };
|
|
18586
18586
|
return asBoardAgentOp({ op: "add", anchor: { page: spec.page, board: v6.board, x: v6.x ?? spec.w, y: v6.y ?? 0 }, text: v6.text });
|
|
18587
18587
|
}
|
|
18588
|
+
var hashCache = /* @__PURE__ */ new Map();
|
|
18588
18589
|
function fileHash(dir, relative) {
|
|
18589
18590
|
const file = resolveBoardFile(dir, relative);
|
|
18590
18591
|
if (!file) return null;
|
|
18591
18592
|
try {
|
|
18592
|
-
|
|
18593
|
+
const stat = import_node_fs8.default.statSync(file);
|
|
18594
|
+
const stamp2 = `${stat.size}:${stat.mtimeMs}`;
|
|
18595
|
+
const cached = hashCache.get(file);
|
|
18596
|
+
if (cached?.stamp === stamp2) return cached.hash;
|
|
18597
|
+
const hash = import_node_crypto2.default.createHash("sha1").update(import_node_fs8.default.readFileSync(file)).digest("hex").slice(0, 12);
|
|
18598
|
+
hashCache.set(file, { stamp: stamp2, hash });
|
|
18599
|
+
return hash;
|
|
18593
18600
|
} catch {
|
|
18594
18601
|
return null;
|
|
18595
18602
|
}
|
|
@@ -18608,7 +18615,12 @@ function stamp(anchor, hashes, groups = {}) {
|
|
|
18608
18615
|
if (!boards.length) return withoutHashes(anchor);
|
|
18609
18616
|
return { ...withoutHashes(anchor), hashes: Object.fromEntries(boards.map((board) => [board, hashes[board] ?? "missing"])) };
|
|
18610
18617
|
}
|
|
18611
|
-
var
|
|
18618
|
+
var sameMembers = (thread, groups) => {
|
|
18619
|
+
const group = thread.anchor.group;
|
|
18620
|
+
if (!group) return true;
|
|
18621
|
+
return Object.keys(thread.anchor.hashes ?? {}).sort().join("\n") === [...groups[group]?.boards ?? []].sort().join("\n");
|
|
18622
|
+
};
|
|
18623
|
+
var isStale = (thread, hashes, groups) => !sameMembers(thread, groups) || Object.entries(thread.anchor.hashes ?? {}).some(([board, hash]) => hashes[board] !== hash);
|
|
18612
18624
|
function createBoardCommentRegistry(options) {
|
|
18613
18625
|
const stores = /* @__PURE__ */ new Map();
|
|
18614
18626
|
const hashes = /* @__PURE__ */ new Map();
|
|
@@ -18633,7 +18645,8 @@ function createBoardCommentRegistry(options) {
|
|
|
18633
18645
|
};
|
|
18634
18646
|
const stale = (id2) => {
|
|
18635
18647
|
const now = currentHashes(id2);
|
|
18636
|
-
|
|
18648
|
+
const groups = groupSpecs(dirOf(id2));
|
|
18649
|
+
return store(id2).current().threads.filter((thread) => isStale(thread, now, groups)).map((thread) => thread.id);
|
|
18637
18650
|
};
|
|
18638
18651
|
const push2 = (id2) => {
|
|
18639
18652
|
const ids = stale(id2);
|
|
@@ -88660,10 +88673,29 @@ function send(res, status, body, headers = {}) {
|
|
|
88660
88673
|
function sendJson(res, status, value) {
|
|
88661
88674
|
send(res, status, JSON.stringify(value), { "Content-Type": MIME2[".json"] });
|
|
88662
88675
|
}
|
|
88663
|
-
function
|
|
88664
|
-
|
|
88665
|
-
|
|
88666
|
-
|
|
88676
|
+
function byteRange(range, size) {
|
|
88677
|
+
const match = range && /^bytes=(\d*)-(\d*)$/.exec(range.trim());
|
|
88678
|
+
if (!match || !match[1] && !match[2]) return null;
|
|
88679
|
+
const start = match[1] ? Number(match[1]) : Math.max(0, size - Number(match[2]));
|
|
88680
|
+
const end = match[1] && match[2] ? Math.min(Number(match[2]), size - 1) : size - 1;
|
|
88681
|
+
return start > end || start >= size ? "unsatisfiable" : { start, end };
|
|
88682
|
+
}
|
|
88683
|
+
function sendFile(res, file, headers = {}, range) {
|
|
88684
|
+
import_node_fs10.default.stat(file, (err, stat) => {
|
|
88685
|
+
if (err || !stat.isFile()) {
|
|
88686
|
+
send(res, 404, "Not found");
|
|
88687
|
+
return;
|
|
88688
|
+
}
|
|
88689
|
+
const base = { "Referrer-Policy": "no-referrer", "Cache-Control": "no-store", "Content-Type": mimeOf(file), "Accept-Ranges": "bytes", ...headers };
|
|
88690
|
+
const part = byteRange(range, stat.size);
|
|
88691
|
+
if (part === "unsatisfiable") {
|
|
88692
|
+
res.writeHead(416, { ...base, "Content-Range": `bytes */${stat.size}` });
|
|
88693
|
+
res.end();
|
|
88694
|
+
return;
|
|
88695
|
+
}
|
|
88696
|
+
if (part) res.writeHead(206, { ...base, "Content-Range": `bytes ${part.start}-${part.end}/${stat.size}`, "Content-Length": String(part.end - part.start + 1) });
|
|
88697
|
+
else res.writeHead(200, { ...base, "Content-Length": String(stat.size) });
|
|
88698
|
+
import_node_fs10.default.createReadStream(file, part ?? {}).on("error", () => res.destroy()).pipe(res);
|
|
88667
88699
|
});
|
|
88668
88700
|
}
|
|
88669
88701
|
|
|
@@ -90071,14 +90103,16 @@ function createAutoPublisher(options) {
|
|
|
90071
90103
|
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
90072
90104
|
var RESOLVE = { artboard: resolveBoardFile, document: resolveDocumentAsset, html: resolveHtmlFile };
|
|
90073
90105
|
var isArtifactPage = (type, relative) => type === "html" ? relative === "index.html" : relative.endsWith(".html");
|
|
90074
|
-
function readArtifactFile(dir, type, relative, uiRuntimeUrl) {
|
|
90106
|
+
function readArtifactFile(dir, type, relative, uiRuntimeUrl, maxBytes = Infinity) {
|
|
90075
90107
|
if (!resolveInside(dir, relative)) return null;
|
|
90076
90108
|
const target = RESOLVE[type](dir, relative);
|
|
90077
90109
|
if (!target) return null;
|
|
90078
90110
|
let data;
|
|
90079
90111
|
try {
|
|
90112
|
+
if (import_node_fs21.default.statSync(target).size > maxBytes) throw new RangeError("too large");
|
|
90080
90113
|
data = import_node_fs21.default.readFileSync(target);
|
|
90081
|
-
} catch {
|
|
90114
|
+
} catch (err) {
|
|
90115
|
+
if (err instanceof RangeError) throw err;
|
|
90082
90116
|
return null;
|
|
90083
90117
|
}
|
|
90084
90118
|
if (!isArtifactPage(type, relative)) return { contentType: mimeOf(target), data };
|
|
@@ -90462,7 +90496,7 @@ async function startArtifactsServer(options) {
|
|
|
90462
90496
|
}
|
|
90463
90497
|
};
|
|
90464
90498
|
const isAuthorized = (req, keyFromQuery) => keyFromQuery !== null && safeEqual(keyFromQuery, token) || safeEqual(parseCookies(req.headers.cookie)[cookieName] ?? "", token);
|
|
90465
|
-
const serveContent = (res, rest) => {
|
|
90499
|
+
const serveContent = (res, rest, range) => {
|
|
90466
90500
|
if (rest.startsWith("runtime/")) {
|
|
90467
90501
|
if (!runtimeDir) {
|
|
90468
90502
|
send(res, 404, "Not found");
|
|
@@ -90498,7 +90532,7 @@ async function startArtifactsServer(options) {
|
|
|
90498
90532
|
const page = ref.type === "html" ? relative === "index.html" : relative.endsWith(".html");
|
|
90499
90533
|
const headers = { "Content-Security-Policy": CONTENT_CSP[page && ref.type === "document" ? "html" : ref.type], "Access-Control-Allow-Origin": "*" };
|
|
90500
90534
|
if (!page) {
|
|
90501
|
-
sendFile(res, target, headers);
|
|
90535
|
+
sendFile(res, target, headers, range);
|
|
90502
90536
|
return;
|
|
90503
90537
|
}
|
|
90504
90538
|
import_node_fs23.default.readFile(target, "utf8", (err, source) => {
|
|
@@ -90598,7 +90632,7 @@ async function startArtifactsServer(options) {
|
|
|
90598
90632
|
}
|
|
90599
90633
|
if (pathname.startsWith("/c/")) {
|
|
90600
90634
|
if (!pathname.startsWith(contentPrefix)) send(res, 404, "Not found");
|
|
90601
|
-
else serveContent(res, pathname.slice(contentPrefix.length));
|
|
90635
|
+
else serveContent(res, pathname.slice(contentPrefix.length), req.headers.range);
|
|
90602
90636
|
return;
|
|
90603
90637
|
}
|
|
90604
90638
|
if (cloud && pathname === "/api/cloud/callback") {
|
|
@@ -90826,7 +90860,7 @@ async function startArtifactsServer(options) {
|
|
|
90826
90860
|
const request = typeof body === "object" && body !== null ? body : {};
|
|
90827
90861
|
if (request.op === "meta") return artifactMeta(ref, dir, contentOrigin);
|
|
90828
90862
|
if (request.op === "file") {
|
|
90829
|
-
const file = typeof request.path === "string" ? readArtifactFile(dir, ref.type, request.path, CLOUD_RUNTIME_URL) : null;
|
|
90863
|
+
const file = typeof request.path === "string" ? readArtifactFile(dir, ref.type, request.path, CLOUD_RUNTIME_URL, MAX_RELAY_FILE) : null;
|
|
90830
90864
|
if (!file) throw new Error("not found");
|
|
90831
90865
|
if (file.data.length > MAX_RELAY_FILE) throw new Error("too large");
|
|
90832
90866
|
return { contentType: file.contentType, data: file.data.toString("base64") };
|
|
@@ -91045,7 +91079,7 @@ function openReady(payload) {
|
|
|
91045
91079
|
}
|
|
91046
91080
|
|
|
91047
91081
|
// package.json
|
|
91048
|
-
var version = "1.
|
|
91082
|
+
var version = "1.18.0";
|
|
91049
91083
|
|
|
91050
91084
|
// src/server/main.ts
|
|
91051
91085
|
async function main() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,t as n}from"./jsx-runtime-CldxteV5.js";import{a as r}from"./useSandboxFrame-N5uRz7Cc.js";import{t as i}from"./index.js";import a from"./CloudDocument-DQ8BLzr7.js";import{DocumentView as o,t as s}from"./DocumentPage-CgCHoFVv.js";var c=e(t(),1),l=`1.
|
|
1
|
+
import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,t as n}from"./jsx-runtime-CldxteV5.js";import{a as r}from"./useSandboxFrame-N5uRz7Cc.js";import{t as i}from"./index.js";import a from"./CloudDocument-DQ8BLzr7.js";import{DocumentView as o,t as s}from"./DocumentPage-CgCHoFVv.js";var c=e(t(),1),l=`1.18.0`,u=e=>/^(\d+)\.(\d+)\./.exec(e??``)?.slice(1,3).join(`.`)??null;function d(e,t){let n=u(e);return n!==null&&n===u(t)}var f=(e,t)=>`电脑上的 ryugi 是 ${t??`未知版本`},网页是 ${e},版本对上之前只能评论`,p=n();function m({id:e,state:t,contentBase:n,liveContentBase:u,comments:m}){let{transport:h,presence:g}=s(e,u??n??``),_=g?.online??!1;r(e,{online:g?.online??null});let[v,y]=(0,c.useState)(!1);if((0,c.useEffect)(()=>{_&&y(!0)},[_]),!h||!(v||_))return!t||!n?(0,p.jsx)(i,{children:g===null?`正在连接…`:`还没发布。电脑在线时,这里会实时显示。`}):(0,p.jsx)(a,{id:e,state:t,contentBase:n,comments:m,offline:g!==null&&!_});let b=_&&d(l,g?.version??null),x=_&&!b?f(l,g?.version??null):null;return(0,p.jsx)(o,{id:e,transport:h,live:_,cloud:{online:_,canEdit:b,reason:x}})}export{m as default};
|