Skip to content

Commit

Permalink
queryLiveEntriesSignal
Browse files Browse the repository at this point in the history
  • Loading branch information
guillemcordoba committed Oct 15, 2024
1 parent e342ffa commit 1b4a9c0
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 42 deletions.
81 changes: 39 additions & 42 deletions packages/signals/package.json
Original file line number Diff line number Diff line change
@@ -1,43 +1,40 @@
{
"name": "@holochain-open-dev/signals",
"version": "0.300.7",
"description": "Holochain async-signals to build reusable holochain-open-dev modules",
"author": "[email protected]",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"exports": {
".": "./dist/index.js",
"./dist/*": "./dist/*"
},
"scripts": {
"start": "vite --open",
"build": "npm run lint && tsc",
"lint": "eslint src",
"test": "vitest run",
"prepublish": "npm run build"
},
"dependencies": {
"@holochain-open-dev/utils": "^0.300.2",
"@holochain/client": "^0.17.1",
"@shoelace-style/shoelace": "^2.11.2",
"async-signals": "^0.1.10",
"lit-signal-watcher": "^0.1.1",
"signal-polyfill": "^0.1.1"
},
"devDependencies": {
"@types/lodash-es": "^4.17.6",
"js-base64": "^3.7.7",
"typescript": "^5.4.0",
"vite": "^4.1.1",
"vitest": "^1.5.0"
},
"publishConfig": {
"access": "public"
},
"type": "module"
}
"name": "@holochain-open-dev/signals",
"version": "0.300.8",
"description": "Holochain async-signals to build reusable holochain-open-dev modules",
"author": "[email protected]",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist", "src"],
"exports": {
".": "./dist/index.js",
"./dist/*": "./dist/*"
},
"scripts": {
"start": "vite --open",
"build": "npm run lint && tsc",
"lint": "eslint src",
"test": "vitest run",
"prepublish": "npm run build"
},
"dependencies": {
"@holochain-open-dev/utils": "^0.300.2",
"@holochain/client": "^0.17.1",
"@shoelace-style/shoelace": "^2.11.2",
"async-signals": "^0.1.10",
"lit-signal-watcher": "^0.1.1",
"signal-polyfill": "^0.1.1"
},
"devDependencies": {
"@types/lodash-es": "^4.17.6",
"js-base64": "^3.7.7",
"typescript": "^5.4.0",
"vite": "^4.1.1",
"vitest": "^1.5.0"
},
"publishConfig": {
"access": "public"
},
"type": "module"
}
105 changes: 105 additions & 0 deletions packages/signals/src/holochain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -837,3 +837,108 @@ export function deletedLinksSignal<

return signal;
}

// Keeps an up to date list of the entries in the agent's source chain for the given entry type
export function queryLiveEntriesSignal<
T,
S extends ActionCommittedSignal<any, any> & any,
>(
client: ZomeClient<S>,
queryEntries: () => Promise<Array<EntryRecord<T>>>,
entry_type: string,
pollIntervalMs: number = 20_000,
): AsyncSignal<Array<EntryRecord<T>>> {
let active = false;
let unsubs: () => void | undefined;
let queriedEntries: Array<EntryRecord<T>> | undefined;
const signal = new Signal.State<AsyncResult<Array<EntryRecord<T>>>>(
{ status: 'pending' },
{
[Signal.subtle.watched]: () => {
active = true;
const fetch = async () => {
if (!active) return;

const nQueriedEntries = await queryEntries().finally(() => {
if (active) {
setTimeout(() => fetch(), pollIntervalMs);
}
});
if (
queriedEntries === undefined ||
!areArrayHashesEqual(
queriedEntries.map(r => r.actionHash),
nQueriedEntries.map(r => r.actionHash),
)
) {
queriedEntries = nQueriedEntries;
signal.set({
status: 'completed',
value: queriedEntries,
});
}
};
fetch().catch(error => {
signal.set({
status: 'error',
error,
});
});
unsubs = client.onSignal(async originalSignal => {
if (!active) return;
if (!(originalSignal as ActionCommittedSignal<any, any>).type) return;
const hcSignal = originalSignal as ActionCommittedSignal<any, any>;

if (
hcSignal.type === 'EntryCreated' &&
hcSignal.app_entry.type === entry_type
) {
const newEntry = new EntryRecord<T>({
entry: {
Present: {
entry_type: 'App',
entry: encode(hcSignal.app_entry),
},
},
signed_action: hcSignal.action,
});
if (!queriedEntries) queriedEntries = [];
queriedEntries.push(newEntry);
signal.set({
status: 'completed',
value: queriedEntries,
});
} else if (hcSignal.type === 'EntryDeleted') {
if (
queriedEntries?.find(
e =>
e.actionHash.toString() ===
hcSignal.action.hashed.content.deletes_address.toString(),
)
) {
queriedEntries = queriedEntries.filter(
e =>
e.actionHash.toString() !==
hcSignal.action.hashed.content.deletes_address.toString(),
);
signal.set({
status: 'completed',
value: queriedEntries,
});
}
}
});
},
[Signal.subtle.unwatched]: () => {
signal.set({
status: 'pending',
});
active = false;
queriedEntries = undefined;
unsubs();
},
},
);

return signal;
}

0 comments on commit 1b4a9c0

Please sign in to comment.