@phpsandbox/sdk 0.3.2 → 0.3.3
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/README.md +38 -0
- package/dist/browser/phpsandbox-sdk.esm.js +145 -74
- package/dist/browser/phpsandbox-sdk.esm.min.js +24 -26
- package/dist/browser/phpsandbox-sdk.iife.js +145 -74
- package/dist/browser/phpsandbox-sdk.iife.min.js +9 -11
- package/dist/publication/index.d.ts +1 -0
- package/dist/publication/index.js +1 -0
- package/dist/publication/instance.d.ts +2 -0
- package/dist/publication/instance.js +7 -0
- package/dist/publication/run.js +2 -76
- package/dist/publication/stream.d.ts +18 -0
- package/dist/publication/stream.js +168 -0
- package/package.json +6 -1
|
@@ -44,9 +44,11 @@ var PHPSandbox = (() => {
|
|
|
44
44
|
PublicationRun: () => PublicationRun,
|
|
45
45
|
RemoteError: () => RemoteError,
|
|
46
46
|
TransportError: () => TransportError,
|
|
47
|
+
createPublicationStreamResponse: () => createPublicationStreamResponse,
|
|
47
48
|
laravelCloudSetupForRepublish: () => laravelCloudSetupForRepublish,
|
|
48
49
|
notebookBuiltinServices: () => notebookBuiltinServices,
|
|
49
|
-
notebookKnownServices: () => notebookKnownServices
|
|
50
|
+
notebookKnownServices: () => notebookKnownServices,
|
|
51
|
+
readPublicationStream: () => readPublicationStream
|
|
50
52
|
});
|
|
51
53
|
|
|
52
54
|
// src/errors/index.ts
|
|
@@ -14832,6 +14834,140 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14832
14834
|
return PublishStreamEventSchema.parse({ type, ...event.data });
|
|
14833
14835
|
});
|
|
14834
14836
|
|
|
14837
|
+
// src/publication/stream.ts
|
|
14838
|
+
async function* readPublicationStream(input, options = {}) {
|
|
14839
|
+
if (input instanceof Response && (!input.ok || !input.body)) {
|
|
14840
|
+
await input.body?.cancel().catch(() => void 0);
|
|
14841
|
+
throw new PHPSandboxError(`Publishing stream is unavailable (HTTP ${input.status}).`);
|
|
14842
|
+
}
|
|
14843
|
+
const stream = input instanceof Response ? input.body : input;
|
|
14844
|
+
const reader = stream.getReader();
|
|
14845
|
+
const decoder = new TextDecoder();
|
|
14846
|
+
let buffer = "";
|
|
14847
|
+
let eventName = "message";
|
|
14848
|
+
let data = [];
|
|
14849
|
+
let ended = false;
|
|
14850
|
+
let receivedResult = false;
|
|
14851
|
+
function dispatch() {
|
|
14852
|
+
const name = eventName;
|
|
14853
|
+
const lines = data;
|
|
14854
|
+
eventName = "message";
|
|
14855
|
+
data = [];
|
|
14856
|
+
if (!lines.length || !PublishStreamSseEventNameSchema.safeParse(name).success) return null;
|
|
14857
|
+
const raw = lines.join("\n");
|
|
14858
|
+
let payload;
|
|
14859
|
+
try {
|
|
14860
|
+
payload = JSON.parse(raw);
|
|
14861
|
+
} catch {
|
|
14862
|
+
payload = raw;
|
|
14863
|
+
}
|
|
14864
|
+
const event = PublishStreamSseEventSchema.parse({ event: name, data: payload });
|
|
14865
|
+
if (event.type === "result") receivedResult = true;
|
|
14866
|
+
return event;
|
|
14867
|
+
}
|
|
14868
|
+
function line(value) {
|
|
14869
|
+
if (value === "") return dispatch();
|
|
14870
|
+
if (value.startsWith(":")) return null;
|
|
14871
|
+
const colon = value.indexOf(":");
|
|
14872
|
+
const field = colon < 0 ? value : value.slice(0, colon);
|
|
14873
|
+
let content = colon < 0 ? "" : value.slice(colon + 1);
|
|
14874
|
+
if (content.startsWith(" ")) content = content.slice(1);
|
|
14875
|
+
if (field === "event") eventName = content;
|
|
14876
|
+
if (field === "data") data.push(content);
|
|
14877
|
+
return null;
|
|
14878
|
+
}
|
|
14879
|
+
try {
|
|
14880
|
+
while (true) {
|
|
14881
|
+
const { done, value } = await reader.read();
|
|
14882
|
+
buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
|
|
14883
|
+
let match;
|
|
14884
|
+
while (match = /\r\n|\r|\n/.exec(buffer)) {
|
|
14885
|
+
if (!done && match[0] === "\r" && match.index === buffer.length - 1) break;
|
|
14886
|
+
const event = line(buffer.slice(0, match.index));
|
|
14887
|
+
buffer = buffer.slice(match.index + match[0].length);
|
|
14888
|
+
if (event) yield event;
|
|
14889
|
+
}
|
|
14890
|
+
if (done) {
|
|
14891
|
+
ended = true;
|
|
14892
|
+
if (buffer) {
|
|
14893
|
+
const event2 = line(buffer);
|
|
14894
|
+
if (event2) yield event2;
|
|
14895
|
+
}
|
|
14896
|
+
const event = dispatch();
|
|
14897
|
+
if (event) yield event;
|
|
14898
|
+
if (options.requireResult !== false && !receivedResult) {
|
|
14899
|
+
throw new PHPSandboxError("Publish stream ended without result");
|
|
14900
|
+
}
|
|
14901
|
+
return;
|
|
14902
|
+
}
|
|
14903
|
+
}
|
|
14904
|
+
} finally {
|
|
14905
|
+
if (!ended) await reader.cancel().catch(() => void 0);
|
|
14906
|
+
reader.releaseLock();
|
|
14907
|
+
}
|
|
14908
|
+
}
|
|
14909
|
+
function createPublicationStreamResponse(stream, options = {}) {
|
|
14910
|
+
const reader = stream.getReader();
|
|
14911
|
+
let disposed = false;
|
|
14912
|
+
let finished = false;
|
|
14913
|
+
let cancellation;
|
|
14914
|
+
let abort;
|
|
14915
|
+
async function dispose() {
|
|
14916
|
+
if (disposed) return;
|
|
14917
|
+
disposed = true;
|
|
14918
|
+
options.signal?.removeEventListener("abort", abort);
|
|
14919
|
+
reader.releaseLock();
|
|
14920
|
+
await options.onDispose?.();
|
|
14921
|
+
}
|
|
14922
|
+
function cancel(reason) {
|
|
14923
|
+
return cancellation ?? (cancellation = (async () => {
|
|
14924
|
+
finished = true;
|
|
14925
|
+
try {
|
|
14926
|
+
await reader.cancel(reason);
|
|
14927
|
+
} finally {
|
|
14928
|
+
await dispose();
|
|
14929
|
+
}
|
|
14930
|
+
})());
|
|
14931
|
+
}
|
|
14932
|
+
return new Response(new ReadableStream({
|
|
14933
|
+
start(controller) {
|
|
14934
|
+
abort = () => {
|
|
14935
|
+
controller.error(options.signal.reason);
|
|
14936
|
+
void cancel(options.signal.reason).catch(() => void 0);
|
|
14937
|
+
};
|
|
14938
|
+
if (options.signal?.aborted) abort();
|
|
14939
|
+
else options.signal?.addEventListener("abort", abort, { once: true });
|
|
14940
|
+
},
|
|
14941
|
+
async pull(controller) {
|
|
14942
|
+
try {
|
|
14943
|
+
const { done, value } = await reader.read();
|
|
14944
|
+
if (finished) return;
|
|
14945
|
+
if (done) {
|
|
14946
|
+
finished = true;
|
|
14947
|
+
await dispose();
|
|
14948
|
+
controller.close();
|
|
14949
|
+
} else {
|
|
14950
|
+
controller.enqueue(value);
|
|
14951
|
+
}
|
|
14952
|
+
} catch (error51) {
|
|
14953
|
+
if (finished && cancellation) return;
|
|
14954
|
+
try {
|
|
14955
|
+
await cancel(error51);
|
|
14956
|
+
} finally {
|
|
14957
|
+
controller.error(error51);
|
|
14958
|
+
}
|
|
14959
|
+
}
|
|
14960
|
+
},
|
|
14961
|
+
cancel
|
|
14962
|
+
}, { highWaterMark: 0 }), {
|
|
14963
|
+
headers: {
|
|
14964
|
+
"Content-Type": "text/event-stream",
|
|
14965
|
+
"Cache-Control": "no-cache, no-transform",
|
|
14966
|
+
"X-Accel-Buffering": "no"
|
|
14967
|
+
}
|
|
14968
|
+
});
|
|
14969
|
+
}
|
|
14970
|
+
|
|
14835
14971
|
// src/publication/run.ts
|
|
14836
14972
|
var PublicationRun = class {
|
|
14837
14973
|
constructor(initial, client) {
|
|
@@ -14919,7 +15055,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14919
15055
|
async consumeStream(eventStreamUrl) {
|
|
14920
15056
|
try {
|
|
14921
15057
|
const stream = await this.client.sse(eventStreamUrl, this.streamAbort.signal);
|
|
14922
|
-
for await (const event of
|
|
15058
|
+
for await (const event of readPublicationStream(stream)) {
|
|
14923
15059
|
this.publish(event);
|
|
14924
15060
|
if (event.type === "result") {
|
|
14925
15061
|
const { type: _, ...result } = event;
|
|
@@ -15020,78 +15156,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15020
15156
|
});
|
|
15021
15157
|
}
|
|
15022
15158
|
};
|
|
15023
|
-
async function* readPublishStreamEvents(stream) {
|
|
15024
|
-
const reader = parseSSEStream(stream).getReader();
|
|
15025
|
-
try {
|
|
15026
|
-
while (true) {
|
|
15027
|
-
const { done, value } = await reader.read();
|
|
15028
|
-
if (done) {
|
|
15029
|
-
return;
|
|
15030
|
-
}
|
|
15031
|
-
const event = parsePublishStreamEvent(value);
|
|
15032
|
-
if (event) {
|
|
15033
|
-
yield event;
|
|
15034
|
-
}
|
|
15035
|
-
}
|
|
15036
|
-
} finally {
|
|
15037
|
-
reader.releaseLock();
|
|
15038
|
-
}
|
|
15039
|
-
}
|
|
15040
|
-
function parsePublishStreamEvent(event) {
|
|
15041
|
-
if (!PublishStreamSseEventNameSchema.safeParse(event.event).success) {
|
|
15042
|
-
return null;
|
|
15043
|
-
}
|
|
15044
|
-
return PublishStreamSseEventSchema.parse(event);
|
|
15045
|
-
}
|
|
15046
|
-
function parseSSEStream(input) {
|
|
15047
|
-
const decoder = new TextDecoder();
|
|
15048
|
-
let buffer = "";
|
|
15049
|
-
return input.pipeThrough(
|
|
15050
|
-
new TransformStream({
|
|
15051
|
-
transform(chunk, controller) {
|
|
15052
|
-
buffer += decoder.decode(chunk, { stream: true });
|
|
15053
|
-
const blocks = buffer.split("\n\n");
|
|
15054
|
-
buffer = blocks.pop() ?? "";
|
|
15055
|
-
for (const block of blocks) {
|
|
15056
|
-
const event = parseSSEBlock(block);
|
|
15057
|
-
if (event) {
|
|
15058
|
-
controller.enqueue(event);
|
|
15059
|
-
}
|
|
15060
|
-
}
|
|
15061
|
-
},
|
|
15062
|
-
flush(controller) {
|
|
15063
|
-
buffer += decoder.decode();
|
|
15064
|
-
if (buffer.trim() !== "") {
|
|
15065
|
-
const event = parseSSEBlock(buffer);
|
|
15066
|
-
if (event) {
|
|
15067
|
-
controller.enqueue(event);
|
|
15068
|
-
}
|
|
15069
|
-
}
|
|
15070
|
-
}
|
|
15071
|
-
})
|
|
15072
|
-
);
|
|
15073
|
-
}
|
|
15074
|
-
function parseSSEBlock(block) {
|
|
15075
|
-
let eventType = "message";
|
|
15076
|
-
let data = "";
|
|
15077
|
-
for (const line of block.split("\n")) {
|
|
15078
|
-
if (line.startsWith("event: ")) {
|
|
15079
|
-
eventType = line.slice(7).trim();
|
|
15080
|
-
} else if (line.startsWith("data: ")) {
|
|
15081
|
-
data += line.slice(6);
|
|
15082
|
-
} else if (line.startsWith("data:")) {
|
|
15083
|
-
data += line.slice(5);
|
|
15084
|
-
}
|
|
15085
|
-
}
|
|
15086
|
-
if (data === "") {
|
|
15087
|
-
return null;
|
|
15088
|
-
}
|
|
15089
|
-
try {
|
|
15090
|
-
return { event: eventType, data: JSON.parse(data) };
|
|
15091
|
-
} catch {
|
|
15092
|
-
return { event: eventType, data };
|
|
15093
|
-
}
|
|
15094
|
-
}
|
|
15095
15159
|
|
|
15096
15160
|
// src/publication/resources.ts
|
|
15097
15161
|
var PublicationResources = class {
|
|
@@ -15183,6 +15247,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15183
15247
|
follow() {
|
|
15184
15248
|
return new PublicationRun(this, this.client).start();
|
|
15185
15249
|
}
|
|
15250
|
+
/** Open the original publishing SSE bytes for an authenticated, transparent proxy. */
|
|
15251
|
+
async stream(signal) {
|
|
15252
|
+
if (!this.data.eventStreamUrl) {
|
|
15253
|
+
throw new PHPSandboxError(`Publication ${this.data.id} has no eventStreamUrl for SSE streaming`);
|
|
15254
|
+
}
|
|
15255
|
+
return this.client.sse(this.data.eventStreamUrl, signal);
|
|
15256
|
+
}
|
|
15186
15257
|
async destroy(options = {}) {
|
|
15187
15258
|
const query = options.deleteResources ? "?deleteResources=1" : "";
|
|
15188
15259
|
await this.client.delete(`/publications/${encodeURIComponent(this.data.id)}${query}`);
|