diff --git a/src/account.ts b/src/account.ts index 03010d4f6..ab8eea08e 100644 --- a/src/account.ts +++ b/src/account.ts @@ -48,7 +48,7 @@ export interface GeneralizedControlledAccount { export class ControlledAccount extends Account implements GeneralizedControlledAccount { agentSecret: AgentSecret; - constructor(agentSecret: AgentSecret, teamMap: CoMap, node: LocalNode) { + constructor(agentSecret: AgentSecret, teamMap: CoMap, node: LocalNode) { super(teamMap, node); this.agentSecret = agentSecret; diff --git a/src/contentType.ts b/src/contentType.ts index 0909c7fc0..6b4eb268c 100644 --- a/src/contentType.ts +++ b/src/contentType.ts @@ -1,24 +1,26 @@ -import { JsonValue } from './jsonValue.js'; -import { RawCoID } from './ids.js'; -import { CoMap } from './contentTypes/coMap.js'; -import { CoStream } from './contentTypes/coStream.js'; -import { Static } from './contentTypes/static.js'; -import { CoList } from './contentTypes/coList.js'; +import { JsonObject, JsonValue } from "./jsonValue.js"; +import { RawCoID } from "./ids.js"; +import { CoMap } from "./contentTypes/coMap.js"; +import { CoStream } from "./contentTypes/coStream.js"; +import { Static } from "./contentTypes/static.js"; +import { CoList } from "./contentTypes/coList.js"; export type CoID = RawCoID & { readonly __type: T; }; export type ContentType = - | CoMap<{[key: string]: JsonValue}, JsonValue> - | CoList - | CoStream - | Static; + | CoMap<{ [key: string]: JsonValue }, JsonObject | null> + | CoList + | CoStream + | Static; -export function expectMap(content: ContentType): CoMap<{ [key: string]: string }, {}> { +export function expectMap( + content: ContentType +): CoMap<{ [key: string]: string }, JsonObject | null> { if (content.type !== "comap") { throw new Error("Expected map"); } - return content as CoMap<{ [key: string]: string }, {}>; + return content as CoMap<{ [key: string]: string }, JsonObject | null>; } diff --git a/src/contentTypes/coList.ts b/src/contentTypes/coList.ts index 41c4d60e1..730ed3937 100644 --- a/src/contentTypes/coList.ts +++ b/src/contentTypes/coList.ts @@ -2,7 +2,7 @@ import { JsonObject, JsonValue } from '../jsonValue.js'; import { CoID } from '../contentType.js'; import { CoValue } from '../coValue.js'; -export class CoList { +export class CoList { id: CoID>; type = "colist" as const; coValue: CoValue; diff --git a/src/contentTypes/coMap.ts b/src/contentTypes/coMap.ts index 523030700..254397745 100644 --- a/src/contentTypes/coMap.ts +++ b/src/contentTypes/coMap.ts @@ -20,24 +20,25 @@ export type MapOpPayload = { key: K; }; +export type MapK = keyof M & string; +export type MapV = M[MapK]; +export type MapM = { + [KK in MapK]: M[KK]; +} + export class CoMap< M extends { [key: string]: JsonValue; }, - Meta extends JsonValue, - K extends string = keyof M & string, - V extends JsonValue = M[K], - MM extends { [key: string]: JsonValue; } = { - [KK in K]: M[KK]; - } + Meta extends JsonObject | null = null, > { - id: CoID>; + id: CoID, Meta>>; coValue: CoValue; type = "comap" as const; ops: { - [KK in K]?: MapOp[]; + [KK in MapK]?: MapOp[]; }; constructor(coValue: CoValue) { - this.id = coValue.id as CoID>; + this.id = coValue.id as CoID, Meta>>; this.coValue = coValue; this.ops = {}; @@ -51,7 +52,7 @@ export class CoMap< for (const [changeIdx, changeUntyped] of ( changes ).entries()) { - const change = changeUntyped as MapOpPayload; + const change = changeUntyped as MapOpPayload, MapV>; let entries = this.ops[change.key]; if (!entries) { entries = []; @@ -61,17 +62,17 @@ export class CoMap< txID, madeAt, changeIdx, - ...(change as MapOpPayload), + ...(change as MapOpPayload, MapV>), }); } } } - keys(): K[] { - return Object.keys(this.ops) as K[]; + keys(): MapK[] { + return Object.keys(this.ops) as MapK[]; } - get(key: KK): M[KK] | undefined { + get>(key: K): M[K] | undefined { const ops = this.ops[key]; if (!ops) { return undefined; @@ -86,7 +87,7 @@ export class CoMap< } } - getAtTime(key: KK, time: number): M[KK] | undefined { + getAtTime>(key: K, time: number): M[K] | undefined { const ops = this.ops[key]; if (!ops) { return undefined; @@ -105,7 +106,7 @@ export class CoMap< } } - getLastTxID(key: KK): TransactionID | undefined { + getLastTxID>(key: K): TransactionID | undefined { const ops = this.ops[key]; if (!ops) { return undefined; @@ -116,7 +117,7 @@ export class CoMap< return lastEntry.txID; } - getLastEntry(key: KK): { at: number; txID: TransactionID; value: M[KK]; } | undefined { + getLastEntry>(key: K): { at: number; txID: TransactionID; value: M[K]; } | undefined { const ops = this.ops[key]; if (!ops) { return undefined; @@ -131,13 +132,13 @@ export class CoMap< } } - getHistory(key: KK): { at: number; txID: TransactionID; value: M[KK] | undefined; }[] { + getHistory>(key: K): { at: number; txID: TransactionID; value: M[K] | undefined; }[] { const ops = this.ops[key]; if (!ops) { return []; } - const history: { at: number; txID: TransactionID; value: M[KK] | undefined; }[] = []; + const history: { at: number; txID: TransactionID; value: M[K] | undefined; }[] = []; for (const op of ops) { if (op.op === "delete") { @@ -178,14 +179,10 @@ export class CoMap< export class WriteableCoMap< M extends { [key: string]: JsonValue; }, - Meta extends JsonValue, - K extends string = keyof M & string, - V extends JsonValue = M[K], - MM extends { [key: string]: JsonValue; } = { - [KK in K]: M[KK]; - } -> extends CoMap { - set(key: KK, value: M[KK], privacy: "private" | "trusting" = "private"): void { + Meta extends JsonObject | null = null, + +> extends CoMap { + set>(key: K, value: M[K], privacy: "private" | "trusting" = "private"): void { this.coValue.makeTransaction([ { op: "insert", @@ -197,7 +194,7 @@ export class WriteableCoMap< this.fillOpsFromCoValue(); } - delete(key: K, privacy: "private" | "trusting" = "private"): void { + delete(key: MapK, privacy: "private" | "trusting" = "private"): void { this.coValue.makeTransaction([ { op: "delete", diff --git a/src/contentTypes/coStream.ts b/src/contentTypes/coStream.ts index 52ddd481e..be479f398 100644 --- a/src/contentTypes/coStream.ts +++ b/src/contentTypes/coStream.ts @@ -2,7 +2,7 @@ import { JsonObject, JsonValue } from '../jsonValue.js'; import { CoID } from '../contentType.js'; import { CoValue } from '../coValue.js'; -export class CoStream { +export class CoStream { id: CoID>; type = "costream" as const; coValue: CoValue; diff --git a/src/contentTypes/static.ts b/src/contentTypes/static.ts index ffa815e66..47c5fdc85 100644 --- a/src/contentTypes/static.ts +++ b/src/contentTypes/static.ts @@ -1,8 +1,8 @@ -import { JsonObject, JsonValue } from '../jsonValue.js'; +import { JsonObject } from '../jsonValue.js'; import { CoID } from '../contentType.js'; import { CoValue } from '../coValue.js'; -export class Static { +export class Static { id: CoID>; type = "static" as const; coValue: CoValue; diff --git a/src/permissions.ts b/src/permissions.ts index d130ca033..87085831c 100644 --- a/src/permissions.ts +++ b/src/permissions.ts @@ -1,6 +1,6 @@ import { CoID, ContentType } from "./contentType.js"; import { CoMap, MapOpPayload } from "./contentTypes/coMap.js"; -import { JsonValue } from "./jsonValue.js"; +import { JsonObject, JsonValue } from "./jsonValue.js"; import { Encrypted, KeyID, @@ -216,24 +216,24 @@ export type TeamContent = { export function expectTeamContent( content: ContentType -): CoMap { +): CoMap { if (content.type !== "comap") { throw new Error("Expected map"); } - return content as CoMap; + return content as CoMap; } export class Team { - teamMap: CoMap; + teamMap: CoMap; node: LocalNode; - constructor(teamMap: CoMap, node: LocalNode) { + constructor(teamMap: CoMap, node: LocalNode) { this.teamMap = teamMap; this.node = node; } - get id(): CoID> { + get id(): CoID> { return this.teamMap.id; } @@ -342,7 +342,7 @@ export class Team { this.rotateReadKey(); } - createMap( + createMap( meta?: M ): CoMap { return this.node