Skip to content

Commit

Permalink
fix each implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
abhishiv committed Jul 25, 2024
1 parent 35c41f2 commit 85a5f6e
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 39 deletions.
2 changes: 1 addition & 1 deletion examples/kitchen-sink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"alfama": "0.9.0"
"alfama": "*"
},
"devDependencies": {
"typescript": "^5.2.2",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "alfama",
"version": "1.1.4",
"version": "1.1.6",
"author": "Abhishiv Saxena<[email protected]>",
"license": "MIT",
"description": "Fine-grained reactive library with no compiler, no magic, and no virtual DOM",
Expand Down
38 changes: 36 additions & 2 deletions src/core/state.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { assert, expect, test, describe, vi } from "vitest";
import { createSignal, createWire, createStore, reify, produce } from "./state";
import {
createSignal,
createWire,
createStore,
reify,
produce,
StoreManager,
StoreChange,
applyStoreChange,
} from "./state";
import { getCursorProxyMeta } from "../utils";

describe("Basic Implementation of Signals & Wires", (test) => {
test("Signal", () => {
Expand All @@ -26,7 +36,7 @@ describe("Nested Signals & Wires", (test) => {
const sig = createSignal(1);
const w = createWire(($, wire) => {
const val = $(sig);
console.log("count", val);
// console.log("count", val);

const b = wire(($, wire) => {
const doubleCount = sig($) * 2;
Expand Down Expand Up @@ -95,4 +105,28 @@ describe("Basic Implementation of Stores & Wires", (test) => {

expect(lSpy.mock.calls.length).toBe(3);
});
test("Test store syncing", () => {
const store1 = createStore<{ a?: any; list: any[] }>({ list: [] });
const store2 = createStore<{ a?: any; list: any[] }>({ list: [] });

const store1Manager: StoreManager =
getCursorProxyMeta<StoreManager>(store1);
const changes: StoreChange[] = [];
store1Manager.tasks.add({
path: [],
observor: (change) => {
changes.push(change);
},
});
produce(store1, (state) => {
state.a = 4;
state.list.push(44);
});
expect(changes.length).toBe(2);
changes.forEach((change) => {
applyStoreChange(store2, change);
});
const store2Value = reify(store2);
expect(JSON.stringify(reify(store1))).toBe(JSON.stringify(reify(store2)));
});
});
30 changes: 26 additions & 4 deletions src/core/state/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export type StoreManager<T = unknown> = {
/** Wires subscribed to this signal */
wires: Set<Wire<any>>;
type: typeof Constants.STORE;
tasks: Set<{ path: string[]; observor: Function }>;
tasks: Set<{
path: string[];
observor: (change: StoreChange) => void;
}>;
unsubscribe: Function;
};

Expand Down Expand Up @@ -320,10 +323,13 @@ export const createStore = <T = unknown>(
}
//console.log([...toRun]);
_runWires(toRun);

//console.log("manager.tasks", manager.tasks);
[...manager.tasks].forEach(({ path, observor }) => {
//console.log({ path, changePath, change });
if (path.join("/") === changePath.join("/")) {
console.log(
changePath.slice(0, path.length).join("/") === path.join("/"),
{ path, changePath, change }
);
if (changePath.slice(0, path.length).join("/") === path.join("/")) {
observor({ data: change, path: changePath, value });
}
});
Expand Down Expand Up @@ -434,3 +440,19 @@ const getSubtoken = (wire: Wire): SubToken => {
token.type = Constants.SUBTOKEN;
return token as SubToken;
};

export const applyStoreChange = (store: CursorProxy, change: StoreChange) => {
if (change.data) {
produce(getValueUsingPath(store, change.path), (state) => {
(state as any)[change.data.name].apply(state, change.data.args);
});
} else {
const tail = change.path[change.path.length - 1];
produce(
getValueUsingPath(store, change.path.slice(0, change.path.length - 1)),
(state) => {
state[tail] = change.value;
}
);
}
};
71 changes: 41 additions & 30 deletions src/stdlib/Each/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,41 @@ export const Each: <T extends ArrayOrObject>(

const cursor = props.cursor;
const store: StoreManager = (cursor as any)[META_FLAG];
const path: string[] = getCursor(cursor);
const eachCursorPath: string[] = getCursor(cursor);
console.log("Each", eachCursorPath);

const value: any[] = getValueUsingPath(store.value as any, path) as any[];
const value: any[] = getValueUsingPath(
store.value as any,
eachCursorPath
) as any[];
const observor = function ({ data, path }: StoreChange) {
//console.debug("change", changes, path);
// important
// filter changes so you don't try to render invalid changes
if (path.slice(0, eachCursorPath.length).join("/") !== path.join("/"))
return;

//console.log("list change", data, path, value);
// console.log("list change", data, path, value);
const pStep = parentStep.children[0];
const previousChildren = [...(pStep.children || [])];
if (data.name === "push") {
const index = (data.result as number) - 1; // push returns new length
const { treeStep, el } = renderArray(
pStep,
props.renderItem,
cursor,
value,
index
);
const { registry, root } = reifyTree(renderContext, el, pStep);
addNode(renderContext, pStep, root);
} else if (data.name === "pop") {
if (data?.name === "push") {
data.args.forEach((arg, i) => {
const index = previousChildren.length + i; // push returns new length
const { treeStep, el } = renderArray(
pStep,
props.renderItem,
cursor,
value,
index
);
const { registry, root } = reifyTree(renderContext, el, pStep);
addNode(renderContext, pStep, root);
});
} else if (data?.name === "pop") {
if (previousChildren.length > 0) {
const lastNode = previousChildren[previousChildren.length - 1];
removeNode(renderContext, lastNode);
}
} else if (data.name === "splice") {
} else if (data?.name === "splice") {
const [startIndex, deleteCount, ...items] = data.args as [
number,
number,
Expand All @@ -106,20 +115,20 @@ export const Each: <T extends ArrayOrObject>(
);
const { registry, root } = reifyTree(renderContext, el, pStep);
const before = previousChildren[startIndex + i] || null;
console.log(previousChildren);
console.log("before", {
startIndex,
i,
before,
pStep,
parentStep,
root,
});
// console.log(previousChildren);
// console.log("before", {
// startIndex,
// i,
// before,
// pStep,
// parentStep,
// root,
// });
addNode(renderContext, pStep, root, before);
});
}
};
const task = { path, observor };
const task = { path: eachCursorPath, observor };
onMount(() => {
store.tasks.add(task);
});
Expand All @@ -140,9 +149,10 @@ export const Each: <T extends ArrayOrObject>(
// object
return (
<Fragment>
{Object.keys(value).map((el, index) =>
props.renderItem((cursor as any)[el], el as any)
)}
{Object.keys(value).map((el, index) => {
// console.log("el", el, index, (cursor as any)[el]);
return props.renderItem((cursor as any)[el], el as any);
})}
</Fragment>
);
}
Expand All @@ -156,6 +166,7 @@ const renderArray = (
list: any[],
index: number | string
) => {
// console.log(getCursor(cursor));
const vEl = renderItem((cursor as any)[index], index);
const treeStep = getTreeStep(parentStep, undefined, vEl);
return { treeStep, el: vEl };
Expand Down
5 changes: 4 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
export const getValueUsingPath = (
record: Record<string, any>,
path: string[]
) => path.reduce((record, item) => record[item], record);
) =>
path.length === 0
? record
: path.reduce((record, item) => record[item], record);

export * from "./crawl";
export * from "./cursor";

0 comments on commit 85a5f6e

Please sign in to comment.