Skip to content

Commit

Permalink
add loaders and actions
Browse files Browse the repository at this point in the history
  • Loading branch information
tlgimenes committed Jan 11, 2024
1 parent 6acb230 commit 1681280
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 175 deletions.
96 changes: 96 additions & 0 deletions admin/actions/releases/fork.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { fjp } from "../../deps.ts";
import { storage } from "../../fsStorage.ts";
import { Acked, Commands, Events, State } from "../../types.ts";

export interface Props {
/** Environment name to connect to */
name: string;
}

const subscribers: WebSocket[] = [];

export const fetchState = async (): Promise<State> => ({
decofile: await storage.state({ forceFresh: true }),
});

const saveState = ({ decofile }: State): Promise<void> =>
storage.update(decofile);

// Apply patch and save state ATOMICALLY!
// This is easily done on play. On production, however, we probably
// need a distributed queue
let queue = Promise.resolve();
const patchState = (ops: fjp.Operation[]) => {
queue = queue.catch(() => null).then(async () =>
saveState(ops.reduce(fjp.applyReducer, await fetchState()))
);

return queue;
};

const action = (_props: Props, req: Request) => {
const { socket, response } = Deno.upgradeWebSocket(req);

const broadcast = (event: Acked<Events>) => {
const message = JSON.stringify(event);
subscribers.forEach((s) => s.send(message));
};
const send = (event: Acked<Events>) => socket.send(JSON.stringify(event));
const parse = (event: MessageEvent<string>): Acked<Commands> =>
JSON.parse(event.data);

const open = () => subscribers.push(socket);
const close = () => subscribers.splice(subscribers.indexOf(socket), 1);
const message = async (event: MessageEvent<string>) => {
const data = parse(event);

const { ack } = data;

if (data.type === "patch-state") {
try {
const { payload: operations } = data;

await patchState(operations);

// Broadcast changes
broadcast({
type: "state-patched",
payload: operations,
etag: await storage.revision(),
metadata: {}, // TODO: add metadataß
ack,
});
} catch ({ name, operation }) {
console.error({ name, operation });
}
} else if (data.type === "fetch-state") {
send({
type: "state-fetched",
payload: await fetchState(),
etag: await storage.revision(),
ack,
});
} else {
console.error("UNKNOWN EVENT", event);
}
};

/**
* Handles the WebSocket connection on open event.
*/
socket.onopen = open;
/**
* Handles the WebSocket connection on close event.
*/
socket.onclose = close;

/**
* Handles the WebSocket connection on message event.
* @param {MessageEvent} event - The WebSocket message event.
*/
socket.onmessage = (e) => message(e).catch(() => {});

return response;
};

export default action;
162 changes: 0 additions & 162 deletions admin/actions/workspaces/connect.ts

This file was deleted.

15 changes: 15 additions & 0 deletions admin/loaders/releases/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { fetchState } from "../../actions/releases/fork.ts";
import { State } from "../../types.ts";

interface Props {
name: string;
}

/** TODO(@gimenes): Implement fetching the state from the proper environment name */
const action = async (_props: Props): Promise<State["decofile"]> => {
const { decofile } = await fetchState();

return decofile;
};

export default action;
22 changes: 12 additions & 10 deletions admin/manifest.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import * as $$$1 from "./loaders/blocks/published.ts";
import * as $$$2 from "./loaders/blocks/latest.ts";
import * as $$$3 from "./loaders/blocks/listRevisions.ts";
import * as $$$4 from "./loaders/state.ts";
import * as $$$5 from "./loaders/releases/blocks.ts";
import * as $$$6 from "./loaders/platforms/forSite.ts";
import * as $$$7 from "./loaders/deploy.ts";
import * as $$$8 from "./loaders/pages/list.ts";
import * as $$$5 from "./loaders/releases/get.ts";
import * as $$$6 from "./loaders/releases/blocks.ts";
import * as $$$7 from "./loaders/platforms/forSite.ts";
import * as $$$8 from "./loaders/deploy.ts";
import * as $$$9 from "./loaders/pages/list.ts";
import * as $$$$$$$$$0 from "./actions/blocks/publish.ts";
import * as $$$$$$$$$1 from "./actions/blocks/restore.ts";
import * as $$$$$$$$$2 from "./actions/blocks/safeDelete.ts";
import * as $$$$$$$$$3 from "./actions/blocks/newRevision.ts";
import * as $$$$$$$$$4 from "./actions/blocks/delete.ts";
import * as $$$$$$$$$5 from "./actions/workspaces/connect.ts";
import * as $$$$$$$$$5 from "./actions/releases/fork.ts";
import * as $$$$$$$$$6 from "./actions/sites/linkRepo.ts";
import * as $$$$$$$$$7 from "./actions/sites/newDomain.ts";
import * as $$$$$$$$$8 from "./actions/sites/unlinkRepo.ts";
Expand All @@ -32,10 +33,11 @@ const manifest = {
"deco-sites/admin/loaders/blocks/listRevisions.ts": $$$3,
"deco-sites/admin/loaders/blocks/published.ts": $$$1,
"deco-sites/admin/loaders/blocks/revision.ts": $$$0,
"deco-sites/admin/loaders/deploy.ts": $$$7,
"deco-sites/admin/loaders/pages/list.ts": $$$8,
"deco-sites/admin/loaders/platforms/forSite.ts": $$$6,
"deco-sites/admin/loaders/releases/blocks.ts": $$$5,
"deco-sites/admin/loaders/deploy.ts": $$$8,
"deco-sites/admin/loaders/pages/list.ts": $$$9,
"deco-sites/admin/loaders/platforms/forSite.ts": $$$7,
"deco-sites/admin/loaders/releases/blocks.ts": $$$6,
"deco-sites/admin/loaders/releases/get.ts": $$$5,
"deco-sites/admin/loaders/state.ts": $$$4,
},
"actions": {
Expand All @@ -49,10 +51,10 @@ const manifest = {
"deco-sites/admin/actions/pages/delete.ts": $$$$$$$$$13,
"deco-sites/admin/actions/pages/new.ts": $$$$$$$$$12,
"deco-sites/admin/actions/pages/publish.ts": $$$$$$$$$11,
"deco-sites/admin/actions/releases/fork.ts": $$$$$$$$$5,
"deco-sites/admin/actions/sites/linkRepo.ts": $$$$$$$$$6,
"deco-sites/admin/actions/sites/newDomain.ts": $$$$$$$$$7,
"deco-sites/admin/actions/sites/unlinkRepo.ts": $$$$$$$$$8,
"deco-sites/admin/actions/workspaces/connect.ts": $$$$$$$$$5,
},
"name": "deco-sites/admin",
"baseUrl": import.meta.url,
Expand Down
35 changes: 35 additions & 0 deletions admin/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
import { type Resolvable } from "deco/engine/core/resolver.ts";
import { type fjp } from "./deps.ts";

export interface Pagination<T> {
data: T[];
page: number;
pageSize: number;
total: number;
}

export interface PatchState {
type: "patch-state";
payload: fjp.Operation[];
}

export interface FetchState {
type: "fetch-state";
}

export interface StatePatched {
type: "state-patched";
payload: fjp.Operation[];
etag: string;
// Maybe add data and user info in here
metadata?: unknown;
}

export interface StateFetched {
type: "state-fetched";
payload: State;
etag: string;
}

export type Acked<T> = T & { ack: string };

export interface State {
decofile: Record<string, Resolvable>;
}

export type Commands = PatchState | FetchState;
export type Events = StatePatched | StateFetched;
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"std/": "https://deno.land/std@0.204.0/",
"partytown/": "https://deno.land/x/partytown@0.4.8/",
"deco-sites/std/": "https://denopkg.com/deco-sites/std@1.22.11/",
"deco/": "https://denopkg.com/deco-cx/deco@1.51.3/"
"deco/": "https://denopkg.com/deco-cx/deco@1.51.4/"
},
"lock": false,
"tasks": {
Expand Down
5 changes: 3 additions & 2 deletions files/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ const compile = async (
): Promise<[AppManifest, SourceMap]> => {
await initializePromise;
const tsModule = await importFromString(content);
const blockPath = join(currdir, blockType, path);
const blockKey = `${manifest.name}/${blockType}/${path}`;
const blockPath = join(currdir, path);
const blockKey = join(manifest.name, path);

return [{
...manifest,
[blockType]: {
Expand Down

0 comments on commit 1681280

Please sign in to comment.