@phpsandbox/sdk 0.3.1 → 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.
@@ -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 readPublishStreamEvents(stream)) {
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}`);
@@ -19650,6 +19721,16 @@ ${JSON.stringify(metadata, null, 2)}` : "";
19650
19721
  async installation() {
19651
19722
  return (await this.client.get(`/servers/${encodeURIComponent(this.data.id)}/installation`)).data;
19652
19723
  }
19724
+ async members(options = {}) {
19725
+ const query = options.page === void 0 ? "" : `?${new URLSearchParams({ page: String(options.page) }).toString()}`;
19726
+ return this.client.get(`/servers/${encodeURIComponent(this.data.id)}/members${query}`);
19727
+ }
19728
+ async share(email3) {
19729
+ return (await this.client.post(`/servers/${encodeURIComponent(this.data.id)}/members`, { email: email3 })).data;
19730
+ }
19731
+ async revokeAccess(memberId) {
19732
+ await this.client.delete(`/servers/${encodeURIComponent(this.data.id)}/members/${encodeURIComponent(String(memberId))}`);
19733
+ }
19653
19734
  refresh() {
19654
19735
  return this.client.servers.get(this.data.id);
19655
19736
  }