Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
narumincho committed Jul 22, 2024
1 parent 9cbf9c9 commit 6cb3238
Show file tree
Hide file tree
Showing 11 changed files with 506 additions and 78 deletions.
96 changes: 96 additions & 0 deletions client/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
type RootContent = {
readonly contents: ReadonlyArray<HashValue<Content>>;
};

/**
* Tのハッシュ値ということ
* value は遅延して渡す
* 内部の定義は適当
*/
type HashValue<T> = {
// readonly hashValue: string;
readonly value: T;
};

/**
* Tの署名ということ
* 内部の定義は適当
*/
type Signature<T> = {
readonly hashValue: HashValue<T>;
readonly value: T;
};

type Content = {
/** 初期ハッシュ値でもある */
readonly id: string;
readonly name: string;
readonly allowWriteAccountIds: ReadonlySet<string>;
readonly contents: ReadonlyArray<Content>;
};

type Commit = {
readonly rootContentHashValue: HashValue<RootContent>;
readonly prevContentHashValue: HashValue<RootContent>;
};

type SignedCommit = {
readonly commitSign: Signature<Commit>;
readonly commitHash: HashValue<Commit>;
};

const getHashContents = (
hashValues: ReadonlySet<string>,
): ReadonlyMap<
string,
{
readonly type: "ok";
readonly content: unknown;
} | {
readonly type: "ng";
readonly reason: "notFound" | "accessDenied";
}
> => {
return new Map();
};

const getLastRootContentHash = (): string => {
return "";
};

/**
* IDたちから最新のハッシュ値を取得する
*
* 最新とはって感じではる. そのサーバーで最新だと思われる...?
*/
const getLastHashByIds = (ids: ReadonlySet<string>): ReadonlyMap<
string,
{
readonly type: "ok";
readonly value: unknown;
} | {
readonly type: "ng";
readonly reason: "notFound";
}
> => {
return new Map();
};

/**
* IDたちからそのrootContentHashのハッシュ値を取得する
*/
const getLastHashByIdsAndRootContentHash = (
ids: ReadonlySet<string>,
rootCotentHash: string,
): ReadonlyMap<
string,
{
readonly type: "ok";
readonly value: unknown;
} | {
readonly type: "ng";
readonly reason: "notFound";
}
> => {
return new Map();
};
1 change: 1 addition & 0 deletions client/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const App = (props: {
readonly signUp: () => void;
readonly copyPassword: () => void;
}) => {
console.log("render App", props);
return (
<div
style={{
Expand Down
27 changes: 27 additions & 0 deletions client/diff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## 編集距離問題

IDがない系だと差分を計算するのが大変である
ただIDを必須にすると指定するのが大変だし,
珍しく同一の変更をした場合に差分として出力してしまうこともある...
(DOMの場合そのことは不便になりえるが...)

動的計画法で文字列を最小操作ポイントで差を埋めるアルゴリズムを書けた.
木構造でこのアルゴリズムは使えるのだろうか?

ものにIDの変更など, 許可されないような操作があったりするな replace というより
update 可能とか, 不可能とか

## 関係ないけど definy

案としてこの世のすべてをモノレポで表現したらどうだろうか?
各ノードでインデックスデータを持つ必要があるが...

- projectA projectAのハッシュ値
- projectB projectBのハッシュ値

から導き出せる すべてのハッシュ値があるが, 使うことはないか?
いわばワールドハッシュみたいな.
projectCを追加するコミットは作成してサーバーAに送信するときに,
サーバーAから「あれが足りないよ」とか要求されるみたいな

著作権などで受理を拒否された場合はハッシュ値とIDだけ残るのかな
11 changes: 11 additions & 0 deletions client/render.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { VDom } from "./vdom.ts";

export const hydrate = (element: Element, vdom: VDom): void => {
requestAnimationFrame(() => {
// console.log("render", element, vdom);
element.querySelector("a")?.insertBefore(a, b);
element.querySelector("a")?.remove();
element.querySelector("a")?.append();
// document.body;
});
};
89 changes: 46 additions & 43 deletions client/start.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,50 @@
import { App } from "./app.tsx";
import { h, hydrate, JSX } from "https://esm.sh/[email protected]?pin=v135";
import { useState } from "https://esm.sh/[email protected]/hooks?pin=v135";
import { utils } from "jsr:@noble/secp256k1";
import { encodeBase64Url } from "jsr:@std/encoding/base64url";
import { SignUpDialog } from "./SignUpDialog.tsx";
import { hydrate } from "./render.ts";
import { div } from "./vdom.ts";
// import { App } from "./app.tsx";
// import { h, hydrate, JSX } from "https://esm.sh/[email protected]?pin=v135";
// import { useState } from "https://esm.sh/[email protected]/hooks?pin=v135";
// import { utils } from "jsr:@noble/secp256k1";
// import { encodeBase64Url } from "jsr:@std/encoding/base64url";
// import { SignUpDialog } from "./SignUpDialog.tsx";

const root = document.getElementById("root");
if (root === null) {
throw new Error("root element not found");
}
// const root = document.getElementById("root");
// if (root === null) {
// throw new Error("root element not found");
// }

const AppWithState = (): JSX.Element => {
const [state, setState] = useState(0);
const [privateKey, setPrivateKey] = useState<Uint8Array | null>(null);
// const AppWithState = (): JSX.Element => {
// const [state, setState] = useState(0);
// const [privateKey, setPrivateKey] = useState<Uint8Array | null>(null);

return (
<div>
<App
state={state}
privateKey={privateKey}
setState={setState}
signUp={() => {
setPrivateKey(utils.randomPrivateKey());
}}
copyPassword={() => {
if (privateKey === null) {
return;
}
navigator.clipboard.writeText(encodeBase64Url(privateKey));
}}
/>
<SignUpDialog
privateKey={privateKey}
copyPassword={() => {
if (privateKey === null) {
return;
}
navigator.clipboard.writeText(encodeBase64Url(privateKey));
}}
onClose={() => setPrivateKey(null)}
/>
</div>
);
};
// return (
// <div>
// <App
// state={state}
// privateKey={privateKey}
// setState={setState}
// signUp={() => {
// setPrivateKey(utils.randomPrivateKey());
// }}
// copyPassword={() => {
// if (privateKey === null) {
// return;
// }
// navigator.clipboard.writeText(encodeBase64Url(privateKey));
// }}
// />
// <SignUpDialog
// privateKey={privateKey}
// copyPassword={() => {
// if (privateKey === null) {
// return;
// }
// navigator.clipboard.writeText(encodeBase64Url(privateKey));
// }}
// onClose={() => setPrivateKey(null)}
// />
// </div>
// );
// };

hydrate(<AppWithState />, root);
// hydrate(<AppWithState />, root);
hydrate(document.documentElement, div({}, "aaa"));
104 changes: 104 additions & 0 deletions client/vdom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// vdom の処理
// レンダリングを要求されたら,
// 前回のvdomと今回のvdomを比較する, 変更点を出力する
// 変更点から実DOMへ反映する

// この構造だとcomponentのように状態管理できん!
// componentの木構造を比較するようにすれば良い?

export type VDom = {
readonly elementName: string;
readonly attributeMap: ReadonlyMap<string, string>;
readonly children: ReadonlyArray<VDom> | string;
};

export const div = (
attribute: { readonly id?: string },
children: ReadonlyArray<VDom> | string,
): VDom => ({
elementName: "div",
attributeMap: new Map([
...(attribute.id
? [
["id", attribute.id],
] as const
: []),
]),
children,
});

export const vdomToString = (vdom: VDom): string =>
`<${vdom.elementName}${
vdom.attributeMap.size === 0
? ""
: ` ${[...vdom.attributeMap].map(([k, v]) => `${k}="${v}"`).join(" ")}`
}>${
typeof vdom.children === "string"
? vdom.children.replaceAll("<", "&gt;")
: vdom.children.map(vdomToString).join("")
}</${vdom.elementName}>`;

export const vdomToHtml = (vdom: VDom): string => {
return "<!doctype html>" + vdomToString(vdom);
};

type Diff = {
readonly type: "remove";
readonly path: ReadonlyArray<number>;
} | {
readonly type: "insertBefore";
readonly path: ReadonlyArray<number>;
readonly newNode: VDom;
readonly index: number | undefined;
} | {
readonly type: "setAttribute";
readonly path: ReadonlyArray<number>;
} | {
readonly type: "setTextContent";
readonly path: ReadonlyArray<number>;
readonly value: string;
} | {
readonly type: "impossible";
};

export const diff = (oldVDom: VDom, newVDom: VDom): ReadonlyArray<Diff> => {
if (typeof newVDom.children === "string") {
if (typeof oldVDom.children === "string") {
if (oldVDom.children === newVDom.children) {
return [];
} else {
return [
{
type: "setTextContent",
path: [],
value: newVDom.children,
},
];
}
} else {
return [
{
type: "setTextContent",
path: [],
value: newVDom.children,
},
];
}
} else {
if (typeof oldVDom.children === "string") {
return newVDom.children.map((child) => ({
type: "insertBefore",
index: undefined,
newNode: child,
path: [],
}));
} else {
// 編集距離とかあるよなぁ...

// A B C
// から
// B D C
// に
}
}
};
Loading

0 comments on commit 6cb3238

Please sign in to comment.