Skip to content

Commit

Permalink
Create workspace app
Browse files Browse the repository at this point in the history
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
  • Loading branch information
mcandeia committed Dec 11, 2023
1 parent 81a3dcf commit 3afeb62
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 32 deletions.
1 change: 1 addition & 0 deletions deco.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const compatibilityApps = [{
const config = {
apps: [
app("ai-assistants"),
app("workspace"),
app("openai"),
app("brand-assistant"),
app("implementation"),
Expand Down
1 change: 1 addition & 0 deletions decohub/apps/workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "../../workspace/mod.ts";
66 changes: 34 additions & 32 deletions decohub/manifest.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,46 @@
import * as $$$$$$$$$$$0 from "./apps/typesense.ts";
import * as $$$$$$$$$$$1 from "./apps/wake.ts";
import * as $$$$$$$$$$$2 from "./apps/ai-assistants.ts";
import * as $$$$$$$$$$$3 from "./apps/analytics.ts";
import * as $$$$$$$$$$$4 from "./apps/workflows.ts";
import * as $$$$$$$$$$$5 from "./apps/implementation.ts";
import * as $$$$$$$$$$$6 from "./apps/vnda.ts";
import * as $$$$$$$$$$$7 from "./apps/algolia.ts";
import * as $$$$$$$$$$$8 from "./apps/admin.ts";
import * as $$$$$$$$$$$9 from "./apps/nuvemshop.ts";
import * as $$$$$$$$$$$10 from "./apps/linx.ts";
import * as $$$$$$$$$$$11 from "./apps/vtex.ts";
import * as $$$$$$$$$$$12 from "./apps/weather.ts";
import * as $$$$$$$$$$$13 from "./apps/brand-assistant.ts";
import * as $$$$$$$$$$$14 from "./apps/sourei.ts";
import * as $$$$$$$$$$$15 from "./apps/shopify.ts";
import * as $$$$$$$$$$$16 from "./apps/handlebars.ts";
import * as $$$$$$$$$$$17 from "./apps/verified-reviews.ts";
import * as $$$$$$$$$$$18 from "./apps/power-reviews.ts";
import * as $$$$$$$$$$$3 from "./apps/workspace.ts";
import * as $$$$$$$$$$$4 from "./apps/analytics.ts";
import * as $$$$$$$$$$$5 from "./apps/workflows.ts";
import * as $$$$$$$$$$$6 from "./apps/implementation.ts";
import * as $$$$$$$$$$$7 from "./apps/vnda.ts";
import * as $$$$$$$$$$$8 from "./apps/algolia.ts";
import * as $$$$$$$$$$$9 from "./apps/admin.ts";
import * as $$$$$$$$$$$10 from "./apps/nuvemshop.ts";
import * as $$$$$$$$$$$11 from "./apps/linx.ts";
import * as $$$$$$$$$$$12 from "./apps/vtex.ts";
import * as $$$$$$$$$$$13 from "./apps/weather.ts";
import * as $$$$$$$$$$$14 from "./apps/brand-assistant.ts";
import * as $$$$$$$$$$$15 from "./apps/sourei.ts";
import * as $$$$$$$$$$$16 from "./apps/shopify.ts";
import * as $$$$$$$$$$$17 from "./apps/handlebars.ts";
import * as $$$$$$$$$$$18 from "./apps/verified-reviews.ts";
import * as $$$$$$$$$$$19 from "./apps/power-reviews.ts";

const manifest = {
"apps": {
"decohub/apps/admin.ts": $$$$$$$$$$$8,
"decohub/apps/admin.ts": $$$$$$$$$$$9,
"decohub/apps/ai-assistants.ts": $$$$$$$$$$$2,
"decohub/apps/algolia.ts": $$$$$$$$$$$7,
"decohub/apps/analytics.ts": $$$$$$$$$$$3,
"decohub/apps/brand-assistant.ts": $$$$$$$$$$$13,
"decohub/apps/handlebars.ts": $$$$$$$$$$$16,
"decohub/apps/implementation.ts": $$$$$$$$$$$5,
"decohub/apps/linx.ts": $$$$$$$$$$$10,
"decohub/apps/nuvemshop.ts": $$$$$$$$$$$9,
"decohub/apps/power-reviews.ts": $$$$$$$$$$$18,
"decohub/apps/shopify.ts": $$$$$$$$$$$15,
"decohub/apps/sourei.ts": $$$$$$$$$$$14,
"decohub/apps/algolia.ts": $$$$$$$$$$$8,
"decohub/apps/analytics.ts": $$$$$$$$$$$4,
"decohub/apps/brand-assistant.ts": $$$$$$$$$$$14,
"decohub/apps/handlebars.ts": $$$$$$$$$$$17,
"decohub/apps/implementation.ts": $$$$$$$$$$$6,
"decohub/apps/linx.ts": $$$$$$$$$$$11,
"decohub/apps/nuvemshop.ts": $$$$$$$$$$$10,
"decohub/apps/power-reviews.ts": $$$$$$$$$$$19,
"decohub/apps/shopify.ts": $$$$$$$$$$$16,
"decohub/apps/sourei.ts": $$$$$$$$$$$15,
"decohub/apps/typesense.ts": $$$$$$$$$$$0,
"decohub/apps/verified-reviews.ts": $$$$$$$$$$$17,
"decohub/apps/vnda.ts": $$$$$$$$$$$6,
"decohub/apps/vtex.ts": $$$$$$$$$$$11,
"decohub/apps/verified-reviews.ts": $$$$$$$$$$$18,
"decohub/apps/vnda.ts": $$$$$$$$$$$7,
"decohub/apps/vtex.ts": $$$$$$$$$$$12,
"decohub/apps/wake.ts": $$$$$$$$$$$1,
"decohub/apps/weather.ts": $$$$$$$$$$$12,
"decohub/apps/workflows.ts": $$$$$$$$$$$4,
"decohub/apps/weather.ts": $$$$$$$$$$$13,
"decohub/apps/workflows.ts": $$$$$$$$$$$5,
"decohub/apps/workspace.ts": $$$$$$$$$$$3,
},
"name": "decohub",
"baseUrl": import.meta.url,
Expand Down
3 changes: 3 additions & 0 deletions workspace/loaders/block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface Props {
name: string;
}
17 changes: 17 additions & 0 deletions workspace/manifest.gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// DO NOT EDIT. This file is generated by deco.
// This file SHOULD be checked into source version control.
// This file is automatically updated during development when running `dev.ts`.

import * as $$$0 from "./loaders/block.ts";

const manifest = {
"loaders": {
"workspace/loaders/block.ts": $$$0,
},
"name": "workspace",
"baseUrl": import.meta.url,
};

export type Manifest = typeof manifest;

export default manifest;
145 changes: 145 additions & 0 deletions workspace/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { SourceMap } from "deco/blocks/app.ts";
import { buildSourceMap } from "deco/blocks/utils.tsx";
import type { App, AppContext as AC, AppManifest } from "deco/mod.ts";
import {
initialize,
transform,
} from "https://deno.land/x/esbuild@v0.19.7/wasm.js";
import { dirname, join } from "std/path/mod.ts";
import manifest, { Manifest } from "./manifest.gen.ts";

const initializePromise = initialize({
wasmURL: "https://deno.land/x/esbuild@v0.19.7/esbuild.wasm",
worker: false,
});

export interface File {
/**
* @format textarea
*/
content: string;
}

export interface Directory {
entries: FileSystemNode[];
}

export const isDir = (node: Directory | File): node is Directory => {
return Array.isArray((node as Directory)?.entries);
};

/**
* @title {{{name}}}
*/
export interface FileSystemNode {
name: string;
value: Directory | File;
}

export interface State {
/**
* @titleBy name
*/
fileSystem: FileSystemNode[];
}

const currdir = dirname(import.meta.url);
const importFromString = async (modData: string) =>
await transform(modData, {
loader: "tsx",
platform: "browser",
target: ["es2022"],
format: "esm",
minify: false,
jsx: "automatic",
jsxImportSource: "preact",
}).then((res) =>
import(`data:application/javascript;base64,${btoa(res.code)}`)
);

const compile = async (
blockType: keyof Omit<AppManifest, "baseUrl" | "name">,
{ path, content }: TsContent,
manifest: AppManifest,
sourceMap: SourceMap,
): Promise<[AppManifest, SourceMap]> => {
await initializePromise;
const tsModule = await importFromString(content);
const blockPath = join(currdir, blockType, path);
const blockKey = `${manifest.name}/${blockType}/${path}`;
return [{
...manifest,
[blockType]: {
...manifest[blockType],
[blockKey]: tsModule,
},
}, {
...sourceMap,
[blockKey]: {
path: blockPath,
content: content,
},
}];
};

export interface FileSystem {
[path: string]: string | FileSystem;
}

const buildFs = (nodes: FileSystemNode[]): FileSystem => {
return nodes.reduce((acc, node) => {
if (isDir(node.value)) {
return {
...acc,
[node.name]: buildFs(node.value.entries),
};
} else {
return {
...acc,
[node.name]: node.value.content,
};
}
}, {});
};

export interface TsContent {
path: string;
content: string;
}
function* walk(
fs: FileSystem | string,
root = "",
): Generator<TsContent> {
if (typeof fs === "string") {
if (!root.endsWith(".ts") && !root.endsWith(".tsx")) return;
return yield { path: root, content: fs };
}
for (const [name, subdir] of Object.entries(fs)) {
yield* walk(subdir, `${root === "" ? "" : `${root}/`}${name}`);
}
}
/**
* @title My Workspace
*/
export default async function App(
{ fileSystem }: State,
): Promise<App<Manifest, FileSystem>> {
const fs = buildFs(fileSystem);
let appManifest = manifest;
let appSourceMap: SourceMap = buildSourceMap(appManifest);
for (const [blockType, blockContentOrFs] of Object.entries(fs)) {
for (const tsContent of walk(blockContentOrFs)) {
const [newManifest, newSourceMap] = await compile(
blockType as keyof Omit<AppManifest, "baseUrl" | "name">,
tsContent,
appManifest,
appSourceMap,
);
appManifest = newManifest;
appSourceMap = newSourceMap;
}
}
return { manifest: appManifest, state: fs, sourceMap: appSourceMap };
}

export type AppContext = AC<Awaited<ReturnType<typeof App>>>;

0 comments on commit 3afeb62

Please sign in to comment.