···77import { email_subscriptions_to_entity } from "drizzle/schema";
88import postgres from "postgres";
99import { getBlocksWithTypeLocal } from "src/hooks/queries/useBlocks";
1010-import { Fact, PermissionToken } from "src/replicache";
1111-import { Attributes } from "src/replicache/attributes";
1010+import type { Fact, PermissionToken } from "src/replicache";
1111+import type { Attribute } from "src/replicache/attributes";
1212import { Database } from "supabase/database.types";
1313import * as Y from "yjs";
1414import { YJSFragmentToString } from "components/Blocks/TextBlock/RenderYJSFragment";
···9090 let { data } = await supabase.rpc("get_facts", {
9191 root: root_entity,
9292 });
9393- let initialFacts = (data as unknown as Fact<keyof typeof Attributes>[]) || [];
9393+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
9494 let firstPage = initialFacts.find((f) => f.attribute === "root/page") as
9595 | Fact<"root/page">
9696 | undefined;
+2-2
app/[leaflet_id]/Leaflet.tsx
···11"use client";
22import { Fact, PermissionToken, ReplicacheProvider } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
33+import type { Attribute } from "src/replicache/attributes";
44import { SelectionManager } from "components/SelectionManager";
55import { Pages } from "components/Pages";
66import {
···16161717export function Leaflet(props: {
1818 token: PermissionToken;
1919- initialFacts: Fact<keyof typeof Attributes>[];
1919+ initialFacts: Fact<Attribute>[];
2020 leaflet_id: string;
2121}) {
2222 return (
+3-4
app/[leaflet_id]/icon.tsx
···11import { ImageResponse } from "next/og";
22-import { Fact } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
22+import type { Fact } from "src/replicache";
33+import type { Attribute } from "src/replicache/attributes";
44import { Database } from "../../supabase/database.types";
55import { createServerClient } from "@supabase/ssr";
66import { parseHSBToRGB } from "src/utils/parseHSB";
···3636 let { data } = await supabase.rpc("get_facts", {
3737 root: rootEntity,
3838 });
3939- let initialFacts =
4040- (data as unknown as Fact<keyof typeof Attributes>[]) || [];
3939+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
4140 let themePageBG = initialFacts.find(
4241 (f) => f.attribute === "theme/card-background",
4342 ) as Fact<"theme/card-background"> | undefined;
+4-4
app/[leaflet_id]/page.tsx
···22import * as Y from "yjs";
33import * as base64 from "base64-js";
4455-import { Fact } from "src/replicache";
66-import { Attributes } from "src/replicache/attributes";
55+import type { Fact } from "src/replicache";
66+import type { Attribute } from "src/replicache/attributes";
77import { YJSFragmentToString } from "components/Blocks/TextBlock/RenderYJSFragment";
88import { Leaflet } from "./Leaflet";
99import { scanIndexLocal } from "src/replicache/utils";
···5353 getRSVPData(res.data.permission_token_rights.map((ptr) => ptr.entity_set)),
5454 getPollData(res.data.permission_token_rights.map((ptr) => ptr.entity_set)),
5555 ]);
5656- let initialFacts = (data as unknown as Fact<keyof typeof Attributes>[]) || [];
5656+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
5757 return (
5858 <PageSWRDataProvider
5959 rsvp_data={rsvp_data}
···8181 let { data } = await supabaseServerClient.rpc("get_facts", {
8282 root: rootEntity,
8383 });
8484- let initialFacts = (data as unknown as Fact<keyof typeof Attributes>[]) || [];
8484+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
8585 let scan = scanIndexLocal(initialFacts);
8686 let firstPage =
8787 scan.eav(rootEntity, "root/page")[0]?.data.value || rootEntity;
+4-6
app/api/rpc/[command]/getFactsFromHomeLeaflets.ts
···11import { z } from "zod";
22-import { Fact } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
22+import type { Fact } from "src/replicache";
33+import type { Attribute } from "src/replicache/attributes";
44import { makeRoute } from "../lib";
55import { Env } from "./route";
66···2020 result: all_facts.data.reduce(
2121 (acc, fact) => {
2222 if (!acc[fact.root_id]) acc[fact.root_id] = [];
2323- acc[fact.root_id].push(
2424- fact as unknown as Fact<keyof typeof Attributes>,
2525- );
2323+ acc[fact.root_id].push(fact as unknown as Fact<Attribute>);
2624 return acc;
2725 },
2828- {} as { [key: string]: Fact<keyof typeof Attributes>[] },
2626+ {} as { [key: string]: Fact<Attribute>[] },
2927 ),
3028 };
3129 }
+3-5
app/api/rpc/[command]/pull.ts
···44 PullResponseV1,
55 VersionNotSupportedResponse,
66} from "replicache";
77-import { Fact } from "src/replicache";
77+import type { Fact } from "src/replicache";
88import { FactWithIndexes } from "src/replicache/utils";
99-import { Attributes } from "src/replicache/attributes";
99+import type { Attributes } from "src/replicache/attributes";
1010import { makeRoute } from "../lib";
1111import { Env } from "./route";
1212···9595 return {
9696 op: "put",
9797 key: f.id,
9898- value: FactWithIndexes(
9999- f as unknown as Fact<keyof typeof Attributes>,
100100- ),
9898+ value: FactWithIndexes(f as unknown as Fact<Attribute>),
10199 } as const;
102100 }),
103101 ],
+2-2
app/home/LeafletList.tsx
···66import { Fact, ReplicacheProvider } from "src/replicache";
77import { LeafletPreview } from "./LeafletPreview";
88import { useIdentityData } from "components/IdentityProvider";
99-import { Attributes } from "src/replicache/attributes";
99+import type { Attribute } from "src/replicache/attributes";
1010import { getIdentityData } from "actions/getIdentityData";
1111import { callRPC } from "app/api/rpc/client";
12121313export function LeafletList(props: {
1414 initialFacts: {
1515- [root_entity: string]: Fact<keyof typeof Attributes>[];
1515+ [root_entity: string]: Fact<Attribute>[];
1616 };
1717}) {
1818 let { data: localLeaflets } = useSWR("leaflets", () => getHomeDocs(), {
+1-1
app/home/LeafletOptions.tsx
···11"use client";
2233import { Menu, MenuItem } from "components/Layout";
44-import { PermissionToken } from "src/replicache";
44+import type { PermissionToken } from "src/replicache";
55import { hideDoc } from "./storage";
66import { useState } from "react";
77import { ButtonPrimary } from "components/Buttons";
+5-6
app/home/icon.tsx
···11import { ImageResponse } from "next/og";
22-import { Fact } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
22+import type { Fact } from "src/replicache";
33+import type { Attribute } from "src/replicache/attributes";
44import { Database } from "../../supabase/database.types";
55import { createServerClient } from "@supabase/ssr";
66import { parseHSBToRGB } from "src/utils/parseHSB";
···4949 let { data } = await supabase.rpc("get_facts", {
5050 root: rootEntity,
5151 });
5252- let initialFacts =
5353- (data as unknown as Fact<keyof typeof Attributes>[]) || [];
5252+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
5453 let themePageBG = initialFacts.find(
5554 (f) => f.attribute === "theme/card-background",
5655 ) as Fact<"theme/card-background"> | undefined;
···6766 return new ImageResponse(
6867 (
6968 // ImageResponse JSX element
7070- (<div style={{ display: "flex" }}>
6969+ <div style={{ display: "flex" }}>
7170 <svg
7271 width="32"
7372 height="32"
···9190 fill={fillColor ? fillColor : "#272727"}
9291 />
9392 </svg>
9494- </div>)
9393+ </div>
9594 ),
9695 // ImageResponse options
9796 {
+2-2
app/home/page.tsx
···11import { cookies } from "next/headers";
22import { Fact, ReplicacheProvider } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
33+import type { Attribute } from "src/replicache/attributes";
44import {
55 ThemeBackgroundProvider,
66 ThemeProvider,
···7676 : undefined,
7777 ]);
7878 let initialFacts =
7979- (homeLeafletFacts.data as unknown as Fact<keyof typeof Attributes>[]) || [];
7979+ (homeLeafletFacts.data as unknown as Fact<Attribute>[]) || [];
80808181 let root_entity = permission_token.root_entity;
8282 let home_docs_initialFacts = allLeafletFacts?.result || {};
+1-1
app/home/storage.ts
···11-import { PermissionToken } from "src/replicache";
11+import type { PermissionToken } from "src/replicache";
22import { mutate } from "swr";
3344export type HomeDoc = {
-1
app/lish/[handle]/[publication]/DraftList.tsx
···11"use client";
2233-import { Fact, ReplicacheProvider } from "src/replicache";
43import { usePublicationRelationship } from "./usePublicationRelationship";
54import { usePublicationContext } from "components/Providers/PublicationContext";
65import Link from "next/link";
+5-6
app/templates/icon.tsx
···22// we could make it different so it's clear it's not your personal colors?
3344import { ImageResponse } from "next/og";
55-import { Fact } from "src/replicache";
66-import { Attributes } from "src/replicache/attributes";
55+import type { Fact } from "src/replicache";
66+import type { Attribute } from "src/replicache/attributes";
77import { Database } from "../../supabase/database.types";
88import { createServerClient } from "@supabase/ssr";
99import { parseHSBToRGB } from "src/utils/parseHSB";
···5252 let { data } = await supabase.rpc("get_facts", {
5353 root: rootEntity,
5454 });
5555- let initialFacts =
5656- (data as unknown as Fact<keyof typeof Attributes>[]) || [];
5555+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
5756 let themePageBG = initialFacts.find(
5857 (f) => f.attribute === "theme/card-background",
5958 ) as Fact<"theme/card-background"> | undefined;
···7069 return new ImageResponse(
7170 (
7271 // ImageResponse JSX element
7373- (<div style={{ display: "flex" }}>
7272+ <div style={{ display: "flex" }}>
7473 <svg
7574 width="32"
7675 height="32"
···9493 fill={fillColor ? fillColor : "#272727"}
9594 />
9695 </svg>
9797- </div>)
9696+ </div>
9897 ),
9998 // ImageResponse options
10099 {
+1-1
components/Blocks/BlockCommands.tsx
···11-import { Fact, ReplicacheMutators } from "src/replicache";
11+import type { Fact, ReplicacheMutators } from "src/replicache";
22import { useUIState } from "src/useUIState";
3344import { generateKeyBetween } from "fractional-indexing";
+1-1
components/Blocks/TextBlock/inputRules.ts
···55} from "prosemirror-inputrules";
66import { MutableRefObject } from "react";
77import { Replicache } from "replicache";
88-import { ReplicacheMutators } from "src/replicache";
88+import type { ReplicacheMutators } from "src/replicache";
99import { BlockProps } from "../Block";
1010import { focusBlock } from "src/utils/focusBlock";
1111import { schema } from "./schema";
+1-1
components/Blocks/TextBlock/keymap.ts
···1212} from "prosemirror-state";
1313import { RefObject } from "react";
1414import { Replicache } from "replicache";
1515-import { ReplicacheMutators } from "src/replicache";
1515+import type { ReplicacheMutators } from "src/replicache";
1616import { elementId } from "src/utils/elementId";
1717import { schema } from "./schema";
1818import { useUIState } from "src/useUIState";
+1-1
components/Blocks/TextBlock/useHandlePaste.ts
···1414import { markdownToHtml } from "src/htmlMarkdownParsers";
1515import { betterIsUrl, isUrl } from "src/utils/isURL";
1616import { TextSelection } from "prosemirror-state";
1717-import { FilterAttributes } from "src/replicache/attributes";
1717+import type { FilterAttributes } from "src/replicache/attributes";
1818import { addLinkBlock } from "src/utils/addLinkBlock";
1919import { UndoManager } from "src/undoManager";
2020
+8-4
src/replicache/attributes.ts
···242242 ...ImageBlockAttributes,
243243 ...PollBlockAttributes,
244244};
245245-type Attribute = typeof Attributes;
245245+export type Attributes = typeof Attributes;
246246+export type Attribute = keyof Attributes;
246247export type Data<A extends keyof typeof Attributes> = {
247248 text: { type: "text"; value: string };
248249 string: { type: "string"; value: string };
···316317 };
317318 color: { type: "color"; value: string };
318319}[(typeof Attributes)[A]["type"]];
319319-export type FilterAttributes<F extends Partial<Attribute[keyof Attribute]>> = {
320320- [A in keyof Attribute as Attribute[A] extends F ? A : never]: Attribute[A];
321321-};
320320+export type FilterAttributes<F extends Partial<Attributes[keyof Attributes]>> =
321321+ {
322322+ [A in keyof Attributes as Attributes[A] extends F
323323+ ? A
324324+ : never]: Attributes[A];
325325+ };
+3-3
src/replicache/clientMutationContext.ts
···3939 },
4040 },
4141 async assertFact(f) {
4242- let attribute = Attributes[f.attribute as keyof typeof Attributes];
4242+ let attribute = Attributes[f.attribute as Attribute];
4343 if (!attribute) return;
4444 let id = f.id || v7();
4545 let data = { ...f.data };
···110110 },
111111 async deleteEntity(entity) {
112112 let existingFacts = await tx
113113- .scan<Fact<keyof typeof Attributes>>({
113113+ .scan<Fact<Attribute>>({
114114 indexName: "eav",
115115 prefix: `${entity}`,
116116 })
117117 .toArray();
118118 let references = await tx
119119- .scan<Fact<keyof typeof Attributes>>({
119119+ .scan<Fact<Attribute>>({
120120 indexName: "vae",
121121 prefix: entity,
122122 })
+7-6
src/replicache/index.tsx
···1717 WriteTransaction,
1818} from "replicache";
1919import { mutations } from "./mutations";
2020-import { Attributes, Data, FilterAttributes } from "./attributes";
2020+import { Attributes } from "./attributes";
2121+import { Attribute, Data, FilterAttributes } from "./attributes";
2122import { clientMutationContext } from "./clientMutationContext";
2223import { supabaseBrowserClient } from "supabase/browserClient";
2324import { callRPC } from "app/api/rpc/client";
···2627import { createUndoManager } from "src/undoManager";
2728import { RealtimeChannel } from "@supabase/supabase-js";
28292929-export type Fact<A extends keyof typeof Attributes> = {
3030+export type Fact<A extends Attribute> = {
3031 id: string;
3132 entity: string;
3233 attribute: A;
···3738 undoManager: createUndoManager(),
3839 rootEntity: "" as string,
3940 rep: null as null | Replicache<ReplicacheMutators>,
4040- initialFacts: [] as Fact<keyof typeof Attributes>[],
4141+ initialFacts: [] as Fact<Attribute>[],
4142 permission_token: {} as PermissionToken,
4243});
4344export function useReplicache() {
···6566};
6667export function ReplicacheProvider(props: {
6768 rootEntity: string;
6868- initialFacts: Fact<keyof typeof Attributes>[];
6969+ initialFacts: Fact<Attribute>[];
6970 token: PermissionToken;
7071 name: string;
7172 children: React.ReactNode;
···191192 );
192193}
193194194194-type CardinalityResult<A extends keyof typeof Attributes> =
195195+type CardinalityResult<A extends Attribute> =
195196 (typeof Attributes)[A]["cardinality"] extends "one"
196197 ? DeepReadonlyObject<Fact<A>> | null
197198 : DeepReadonlyObject<Fact<A>>[];
198198-export function useEntity<A extends keyof typeof Attributes>(
199199+export function useEntity<A extends Attribute>(
199200 entity: string | null,
200201 attribute: A,
201202): CardinalityResult<A> {
···7777 },
7878 async assertFact(f) {
7979 if (!f.entity) return;
8080- let attribute = Attributes[f.attribute as keyof typeof Attributes];
8080+ let attribute = Attributes[f.attribute as Attribute];
8181 if (!attribute) return;
8282 let id = f.id || v7();
8383 let data = { ...f.data };
+5-8
src/replicache/utils.ts
···11import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
22import * as driz from "drizzle-orm";
33-import { Fact } from ".";
33+import type { Fact } from ".";
44import { replicache_clients } from "drizzle/schema";
55-import { Attributes, FilterAttributes } from "./attributes";
55+import type { Attribute, FilterAttributes } from "./attributes";
66import { ReadTransaction, WriteTransaction } from "replicache";
7788-export function FactWithIndexes(f: Fact<keyof typeof Attributes>) {
88+export function FactWithIndexes(f: Fact<Attribute>) {
99 let indexes: {
1010 eav: string;
1111 aev: string;
···4242}
43434444export const scanIndex = (tx: ReadTransaction) => ({
4545- async eav<A extends keyof typeof Attributes>(
4646- entity: string,
4747- attribute: A | "",
4848- ) {
4545+ async eav<A extends Attribute>(entity: string, attribute: A | "") {
4946 return (
5047 (
5148 await tx
···6966});
70677168export const scanIndexLocal = (initialFacts: Fact<any>[]) => ({
7272- eav<A extends keyof typeof Attributes>(entity: string, attribute: A) {
6969+ eav<A extends Attribute>(entity: string, attribute: A) {
7370 return initialFacts.filter(
7471 (f) => f.entity === entity && f.attribute === attribute,
7572 ) as Fact<A>[];
+1-1
src/utils/addImage.ts
···11import { Replicache } from "replicache";
22import { ReplicacheMutators } from "../replicache";
33import { supabaseBrowserClient } from "supabase/browserClient";
44-import { FilterAttributes } from "src/replicache/attributes";
44+import type { FilterAttributes } from "src/replicache/attributes";
55import { rgbaToDataURL, rgbaToThumbHash, thumbHashToDataURL } from "thumbhash";
66import { v7 } from "uuid";
77
+1-1
src/utils/addLinkBlock.ts
···44 LinkPreviewMetadataResult,
55} from "app/api/link_previews/route";
66import { Replicache } from "replicache";
77-import { ReplicacheMutators } from "src/replicache";
77+import type { ReplicacheMutators } from "src/replicache";
88import { AtpAgent } from "@atproto/api";
99import { v7 } from "uuid";
1010
+1-1
src/utils/copySelection.ts
···11import { getBlocksAsHTML } from "src/utils/getBlocksAsHTML";
22import { htmlToMarkdown } from "src/htmlMarkdownParsers";
33import { Replicache } from "replicache";
44-import { ReplicacheMutators } from "src/replicache";
44+import type { ReplicacheMutators } from "src/replicache";
55import { Block } from "components/Blocks/Block";
6677export async function copySelection(
+1-1
src/utils/getBlocksAsHTML.tsx
···11import { ReadTransaction, Replicache } from "replicache";
22-import { Fact, ReplicacheMutators } from "src/replicache";
22+import type { Fact, ReplicacheMutators } from "src/replicache";
33import { scanIndex } from "src/replicache/utils";
44import { renderToStaticMarkup } from "react-dom/server";
55import * as Y from "yjs";
+1-1
src/utils/list-operations.ts
···11import { Block } from "components/Blocks/Block";
22import { Replicache } from "replicache";
33-import { ReplicacheMutators } from "src/replicache";
33+import type { ReplicacheMutators } from "src/replicache";
44import { useUIState } from "src/useUIState";
55import { v7 } from "uuid";
66