M client.lock.json => client.lock.json +0 -1
@@ 77,7 77,6 @@
"https://esm.sh/@codemirror/lang-css": "f3b71966aa75132128e8a0c415e59bd96620d697b1c5b51619c24945418ce1d7",
"https://esm.sh/@codemirror/lang-html": "8d9a06fed93624841b39e58eb7e7fe9f51b24247eda5e156ac1ef9ae5f842793",
"https://esm.sh/@codemirror/lang-javascript": "714f46688fed08019202f2dc4c06049ce021467264e20e87f8df270d6e6ce993",
- "https://esm.sh/@codemirror/text": "b2dc393b8c489623905242b37a5304fea11cd6dfd27e65385ee53e7f0984c7cb",
"https://esm.sh/diffhtml": "f1b48c5bdbb132c3e3be42df7ada0d964b814756dba4f9655e1ba5d00ee0d683",
"https://esm.sh/fast-equals@2.0.4": "92ecadf7e117c0d565df9fa66283217294cc8c9f80ee1a9c38d1f14f2e1f0104",
"https://thelanding.page/tag/tag.js": "4ce4546980b23770c215bbd79923634f253ddf8914bd111beb0a6f43141ce464",
M public/editor.bundle.js => public/editor.bundle.js +31 -12
@@ 17866,11 17866,14 @@ import('https://esm.sh/fast-equals@2.0.4').then(({ deepEqual })=>equal = deepEq
);
const editors = {
};
+const autosave = upload.bind(null, 'autosave');
+const save1 = upload.bind(null, 'save');
function createEditor(selector, flags = {
}) {
const $ = tag(selector);
mount1($, flags);
- autosave($, {
+ onSave($, flags);
+ onAutosave($, {
every: 5
});
}
@@ 17907,23 17910,39 @@ function mount1($, flags) {
});
});
}
-function autosave($, { every }) {
- setInterval(()=>each($, save)
+function onAutosave($, { every }) {
+ setInterval(()=>each($, (target)=>{
+ autosave(target.id, $);
+ })
, every * 1000);
- function save(target) {
- const currentState = $.read();
- const copy = currentState[target.id];
- console.log({
- copy
+}
+function onSave($, _flags) {
+ $.on('click', '[data-save]', (event)=>{
+ save1(event.target.id, $);
+ });
+}
+async function upload(mode, pathname, $) {
+ const currentState = $.read();
+ const { value } = currentState[pathname] || {
+ };
+ if (value) {
+ const response = await fetch(pathname, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ mode,
+ value
+ })
});
+ console.log(response);
}
}
-function persist(target, $, flags) {
+function persist(target, $, _flags) {
return (transaction)=>{
if (transaction.changes.inserted.length < 0) return;
- console.log({
- transaction
- });
const { id } = target;
const { view } = editors[id];
const value = view.state.doc.toString();
M public/editor.js => public/editor.js +37 -12
@@ 3,7 3,6 @@ import {
EditorView,
basicSetup
} from "https://esm.sh/@codemirror/basic-setup"
-import Text from "https://esm.sh/@codemirror/text"
import {
css
} from "https://esm.sh/@codemirror/lang-css"
@@ 18,11 17,15 @@ import tag
const editors = {}
+const autosave = upload.bind(null, 'autosave')
+const save = upload.bind(null, 'save')
+
export default function createEditor(selector, flags = {}) {
const $ = tag(selector)
mount($, flags)
- autosave($, { every: 5 })
+ onSave($, flags)
+ onAutosave($, { every: 5 })
}
const config = {
@@ 64,22 67,44 @@ function mount($, flags) {
})
}
-function autosave($, { every }) {
- setInterval(() => each($, save), every * 1000)
+function onAutosave($, { every }) {
+ setInterval(() => each($, (target) => {
+ autosave(target.id, $)
+ }), every * 1000)
+}
+
+function onSave($, _flags) {
+ $.on('click', '[data-save]', (event) => {
+ save(event.target.id, $)
+ })
+}
- function save(target) {
- const currentState = $.read()
- const copy = currentState[target.id]
+async function upload(mode, pathname, $) {
+ const currentState = $.read()
+ const { value } = currentState[pathname] || {}
- // persist to some back up location
- console.log({ copy })
- }
+ if(value) {
+ // persist to some back up location
+ const response = await fetch(pathname, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ mode,
+ value
+ })
+ });
+
+ console.log(response)
+ }
}
-function persist(target, $, flags) {
+
+function persist(target, $, _flags) {
return (transaction) => {
if(transaction.changes.inserted.length < 0) return
- console.log({ transaction })
const { id } = target
const { view } = editors[id]
const value = view.state.doc.toString()
M server.js => server.js +85 -42
@@ 1,54 1,97 @@
import { serve } from "https://deno.land/std@0.114.0/http/server.ts";
+const methods = {
+ 'GET': handleGet,
+ 'POST': handlePost,
+}
+
+const modes = {
+ 'autosave': autosave,
+ 'save': save,
+}
+
+async function autosave(pathname, params) {
+ const { value } = params
+console.log('why')
+ await Deno.writeTextFile(`./public${pathname}.autosave`, value)
+ return editor(request)
+}
+
+async function save(pathname, params) {
+ const { value } = params
+ await Deno.writeTextFile(`./public${pathname}`, value)
+ return editor(request)
+}
+
async function handleRequest(request) {
- const { pathname } = new URL(request.url);
-
- if (pathname.startsWith("/public")) {
- const file = await Deno.readFile(`.${pathname}`)
- const extension = pathname.split('.').slice(-1)
- return new Response(file, {
- headers: {
- "content-type": getType(extension),
- },
- })
- }
-
- return new Response(`
+ return await (methods[request.method] || methods['POST'])(request)
+}
+
+async function handlePost(request) {
+ const { pathname } = new URL(request.url);
+ const params = await request.json()
+
+ return (modes[params.mode] || function(){})(pathname, params)
+}
+
+async function handleGet(request) {
+ const { pathname } = new URL(request.url);
+
+ const isAutosave = pathname.split('.').slice(-1) === 'autosave'
+ const extensionPosition = isAutosave ? -2 : -1
+
+ if (pathname.startsWith('/public')) {
+ const file = await Deno.readFile(`.${pathname}`)
+ const extension = pathname.split('.').slice(extensionPosition)
+ return new Response(file, {
+ headers: {
+ 'content-type': getType(extension),
+ },
+ })
+ }
+
+ return editor(request)
+}
+
+function editor(request) {
+ const { pathname } = new URL(request.url);
+
+ return new Response(`
<!doctype html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>
- ${pathname}
- </title>
- </head>
- <body>
- <main
- class="source-code"
- id="${pathname}"
- ></main>
- <script type="module">
- import createEditor
- from '/public/editor.bundle.js'
-
- console.log({ createEditor })
-
- createEditor('.source-code')
- </script>
- </body>
- </html>
+ <html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>
+ ${pathname}
+ </title>
+ </head>
+ <body>
+ <main
+ class="source-code"
+ id="${pathname}"
+ ></main>
+ <script type="module">
+ import createEditor
+ from '/public/editor.bundle.js'
+
+ console.log({ createEditor })
+
+ createEditor('.source-code')
+ </script>
+ </body>
+ </html>
`,
- {
- headers: {
- "content-type": getType('html'),
- },
- },
- )
+ {
+ headers: {
+ "content-type": getType('html'),
+ },
+ },
+ )
}
const types = {
'css': 'text/css; charset=utf-8',
- 'html': 'text/html; charset=utf-8',
+ 'html': 'text/html; charset=utf-8',
'js': 'text/javascript; charset=utf-8'
}