Evaluation of signal-libraries and their integration in frontend-frameworks with nested objects using js proxies.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

121 lines
3.8 KiB

<script lang="ts">
import useShape from "../../ng-mock/js-land/frontendAdapters/svelte/useShape.svelte";
import flattenObject from "../utils/flattenObject";
const shapeObject = useShape("TestShape");
function getNestedValue(obj: any, path: string) {
return path
.split(".")
.reduce((cur, k) => (cur == null ? cur : cur[k]), obj);
}
function setNestedValue(obj: any, path: string, value: any) {
const keys = path.split(".");
let cur = obj;
for (let i = 0; i < keys.length - 1; i++) {
cur = cur[keys[i]];
if (cur == null) return;
}
cur[keys[keys.length - 1]] = value;
}
const flatEntries = $derived(
$shapeObject ? flattenObject($shapeObject as any) : []
);
$effect(() => {
(window as any).svelteState = $shapeObject;
});
</script>
{#if $shapeObject}
<div>
<p>Rendered in Svelte</p>
<table border="1" cellpadding="5">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
{#each flatEntries as [key, value] (key)}
<tr>
<td style="white-space:nowrap;">{key}</td>
<td>
{#if value instanceof Set}
{Array.from(value).join(", ")}
{:else if Array.isArray(value)}
[{value.join(", ")}]
{:else}
{JSON.stringify(value)}
{/if}
</td>
<td>
{#if typeof value === "string"}
<input
type="text"
{value}
oninput={(e: any) =>
setNestedValue($shapeObject, key, e.target.value)}
/>
{:else if typeof value === "number"}
<input
type="number"
{value}
oninput={(e: any) =>
setNestedValue($shapeObject, key, Number(e.target.value))}
/>
{:else if typeof value === "boolean"}
<input
type="checkbox"
checked={value}
onchange={(e: any) =>
setNestedValue($shapeObject, key, e.target.checked)}
/>
{:else if Array.isArray(value)}
<div style="display:flex; gap:.5rem;">
<button
onclick={() => {
const cur = getNestedValue($shapeObject, key) || [];
setNestedValue($shapeObject, key, [
...cur,
cur.length + 1,
]);
}}>Add</button
>
<button
onclick={() => {
const cur = getNestedValue($shapeObject, key) || [];
if (cur.length)
setNestedValue($shapeObject, key, cur.slice(0, -1));
}}>Remove</button
>
</div>
{:else if value instanceof Set}
<div style="display:flex; gap:.5rem;">
<button
onclick={() => {
const cur: Set<any> = getNestedValue($shapeObject, key);
cur.add(`item${cur.size + 1}`);
}}>Add</button
>
<button
onclick={() => {
const cur: Set<any> = getNestedValue($shapeObject, key);
const last = Array.from(cur).pop();
if (last !== undefined) cur.delete(last);
}}>Remove</button
>
</div>
{:else}
N/A
{/if}
</td>
</tr>
{/each}
</tbody>
</table>
</div>
{:else}
<p>Loading state</p>
{/if}