Skip to content

Commit d2b3026

Browse files
feat(plugin-stack-persistence): compose strategies
1 parent f52b5f4 commit d2b3026

3 files changed

Lines changed: 60 additions & 1 deletion

File tree

.changeset/shaggy-foxes-compose.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@stackflow/plugin-stack-persistence": minor
3+
---
4+
5+
Add `composeStrategies` to combine keyed snapshot metadata reuse strategies.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { StackSnapshotStrategy } from "./StackSnapshotStrategy";
2+
3+
type StrategiesMetadata<
4+
Strategies extends Record<string, StackSnapshotStrategy<unknown>>,
5+
> = {
6+
[Key in keyof Strategies]: Strategies[Key] extends StackSnapshotStrategy<
7+
infer Metadata
8+
>
9+
? Metadata
10+
: never;
11+
};
12+
13+
function isMetadataRecord(
14+
metadata: unknown,
15+
): metadata is Record<string, unknown> {
16+
return (
17+
typeof metadata === "object" &&
18+
metadata !== null &&
19+
!Array.isArray(metadata)
20+
);
21+
}
22+
23+
export function composeStrategies<
24+
Strategies extends Record<string, StackSnapshotStrategy<unknown>>,
25+
>(
26+
strategies: Strategies,
27+
): StackSnapshotStrategy<StrategiesMetadata<Strategies>> {
28+
const keys = Object.keys(strategies) as Array<keyof Strategies>;
29+
30+
return {
31+
createMetadata(args) {
32+
return Object.fromEntries(
33+
keys.map((key) => [key, strategies[key].createMetadata(args)]),
34+
) as StrategiesMetadata<Strategies>;
35+
},
36+
shouldReuse({ record, initialContext }) {
37+
if (!isMetadataRecord(record.metadata)) return false;
38+
if (!keys.every((key) => Object.hasOwn(record.metadata, key))) {
39+
return false;
40+
}
41+
42+
return keys.every((key) => {
43+
return strategies[key].shouldReuse({
44+
record: {
45+
...record,
46+
metadata: record.metadata[key],
47+
},
48+
initialContext,
49+
});
50+
});
51+
},
52+
};
53+
}

extensions/plugin-stack-persistence/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
export { composeStrategies } from "./composeStrategies";
12
export {
3+
StackSnapshotRecordLoadError,
24
StackSnapshotRecordSaveError,
3-
StackSnapshotRecordLoadError
45
} from "./errors";
56
export { StackSnapshotRecord } from "./StackSnapshotRecord";
67
export { StackSnapshotStorage } from "./StackSnapshotStorage";

0 commit comments

Comments
 (0)