document-model 6.0.2-staging.8 → 6.1.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -17
- package/dist/index.js.map +1 -1
- package/dist/node.d.mts.map +1 -1
- package/dist/node.mjs +2 -8
- package/dist/node.mjs.map +1 -1
- package/package.json +11 -7
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/controller.ts","../src/logger-types.ts","../src/logger.ts","../src/module.ts","../src/state.ts"],"mappings":";;;;KAcK,qBAAA,qBACH,CAAA,4CACO,SAAA,CAAU,IAAA,IAAQ,UAAA,CAAW,qBAAA,CAAsB,IAAA,OACtD,SAAA,CAAU,CAAA;AAAA,KAEJ,mBAAA,gBAAmC,WAAA,GAAc,WAAA;EAC3D,QAAA,EAAU,UAAA,CAAW,MAAA;AAAA;AAAA,KAGX,sBAAA,gBAAsC,WAAA,GAAc,WAAA,KAC9D,KAAA,EAAO,mBAAA,CAAoB,MAAA;AAAA,KAGjB,SAAA,iBAA0B,MAAA,6BAC7B,OAAA,GAAU,cAAA,aAA2B,qBAAA,CAAsB,CAAA,KAChE,KAAA,EAAO,OAAA,CAAQ,OAAA,GAAU,cAAA;EAAkB,IAAA,EAAM,CAAA;AAAA,gBAC9C,OAAA,GAAU,SAAA,CAAU,OAAA,EAAS,OAAA;AAAA,cAGvB,oBAAA,gBACI,WAAA,aACJ,UAAA,CAAW,MAAA;EAAA,SACb,MAAA,EAAQ,mBAAA,CAAoB,MAAA;EAAA,UAC3B,SAAA,EAAW,UAAA,CAAW,MAAA;EAAA,QACxB,SAAA;cAGN,MAAA,EAAQ,mBAAA,CAAoB,MAAA,GAC5B,eAAA,GAAkB,UAAA,CAAW,MAAA;EAAA,IAkB3B,QAAA,CAAA,GAAY,UAAA,CAAW,MAAA;EAAA,IAIvB,MAAA,CAAA,GAAU,gBAAA;EAAA,IAGV,KAAA,CAAA,GAAS,MAAA;EAAA,IAGT,YAAA,CAAA,GAAgB,MAAA;EAAA,IAGhB,UAAA,CAAA,GAAc,kBAAA;EAAA,IAGd,SAAA,CAAA,GAAa,SAAA;EAIjB,QAAA,CAAS,QAAA,EAAU,sBAAA,CAAuB,MAAA;EAAA,QAOlC,eAAA;EAAA,OAQD,gBAAA,gBAAgC,WAAA,kBAA6B,MAAA,CAAA,CAClE,MAAA,EAAQ,mBAAA,CAAoB,MAAA,SAO1B,eAAA,GAAkB,UAAA,CAAW,MAAA,MAC1B,oBAAA,CAAqB,MAAA,IACxB,SAAA,CAAU,OAAA,EAAS,oBAAA,CAAqB,MAAA;AAAA;AAAA,cAIjC,uBAAA,OAAuB,eAAA,GAAA,UAAA,CAAA,oBAAA,kBAAA,oBAAA,CAAA,oBAAA,IAAA,SAAA,CAAA,mBAAA,EAAA,oBAAA,CAAA,oBAAA;;;KC7GxB,kBAAA,OAAyB,IAAA;AAAA,KAEzB,OAAA;EACV,KAAA;EAEA,OAAA,GAAU,OAAA,aAAoB,YAAA;EAC9B,KAAA,GAAQ,OAAA,aAAoB,YAAA;EAC5B,IAAA,GAAO,OAAA,aAAoB,YAAA;EAC3B,IAAA,GAAO,OAAA,aAAoB,YAAA;EAC3B,KAAA,GAAQ,OAAA,aAAoB,YAAA;EAE5B,YAAA,EAAc,kBAAA;EAEd,KAAA,GAAQ,IAAA,eAAmB,OAAA;AAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/controller.ts","../src/logger-types.ts","../src/logger.ts","../src/module.ts","../src/state.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -114,7 +114,25 @@ const dtf = new Intl.DateTimeFormat(void 0, {
|
|
|
114
114
|
second: "2-digit",
|
|
115
115
|
fractionalSecondDigits: 2
|
|
116
116
|
});
|
|
117
|
-
const
|
|
117
|
+
const stringify = (value, includeStack) => {
|
|
118
|
+
if (value === null || value === void 0) return "null";
|
|
119
|
+
if (typeof value === "string") return value;
|
|
120
|
+
if (value instanceof Error) {
|
|
121
|
+
const base = `${value.name}: ${value.message}`;
|
|
122
|
+
return includeStack && value.stack ? `${base}\n${value.stack}` : base;
|
|
123
|
+
}
|
|
124
|
+
if (typeof value === "object") try {
|
|
125
|
+
return JSON.stringify(value);
|
|
126
|
+
} catch {
|
|
127
|
+
return String(value);
|
|
128
|
+
}
|
|
129
|
+
if (typeof value === "function") {
|
|
130
|
+
const name = value.name;
|
|
131
|
+
return name ? `${name}()` : "anonymous()";
|
|
132
|
+
}
|
|
133
|
+
return String(value);
|
|
134
|
+
};
|
|
135
|
+
const formatMessage = (tagString, message, replacements, includeStack) => {
|
|
118
136
|
const meta = {};
|
|
119
137
|
const uniqueTokens = [];
|
|
120
138
|
let results;
|
|
@@ -125,17 +143,9 @@ const formatMessage = (tagString, message, replacements) => {
|
|
|
125
143
|
meta[tokenName] = replacements[uniqueTokens.length - 1];
|
|
126
144
|
}
|
|
127
145
|
}
|
|
128
|
-
for (const [key, value] of Object.entries(meta)) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
else if (typeof value === "string") stringValue = value;
|
|
132
|
-
else if (typeof value === "object") stringValue = JSON.stringify(value);
|
|
133
|
-
else if (typeof value === "function") {
|
|
134
|
-
const name = value.name;
|
|
135
|
-
stringValue = name ? `${name}()` : "anonymous()";
|
|
136
|
-
} else stringValue = String(value);
|
|
137
|
-
message = message.replaceAll(`@${key}`, stringValue);
|
|
138
|
-
}
|
|
146
|
+
for (const [key, value] of Object.entries(meta)) message = message.replaceAll(`@${key}`, stringify(value, includeStack));
|
|
147
|
+
const extras = replacements.slice(uniqueTokens.length);
|
|
148
|
+
if (extras.length > 0) message = `${message} ${extras.map((v) => stringify(v, includeStack)).join(" ")}`;
|
|
139
149
|
if (tagString.length > 0) message = `${tagString} ${message}`;
|
|
140
150
|
const now = /* @__PURE__ */ new Date();
|
|
141
151
|
meta["timestamp"] = dtf.format(now);
|
|
@@ -169,33 +179,36 @@ var ConsoleLogger = class ConsoleLogger {
|
|
|
169
179
|
logger.level = this.level;
|
|
170
180
|
return logger;
|
|
171
181
|
}
|
|
182
|
+
get #includeStack() {
|
|
183
|
+
return this.#level <= LOG_LEVELS.debug;
|
|
184
|
+
}
|
|
172
185
|
verbose(message, ...replacements) {
|
|
173
186
|
if (this.#level <= LOG_LEVELS.verbose) {
|
|
174
|
-
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements);
|
|
187
|
+
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements, this.#includeStack);
|
|
175
188
|
console.debug(`[${meta["timestamp"]}] ${formattedMessage}`);
|
|
176
189
|
}
|
|
177
190
|
}
|
|
178
191
|
debug(message, ...replacements) {
|
|
179
192
|
if (this.#level <= LOG_LEVELS.debug) {
|
|
180
|
-
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements);
|
|
193
|
+
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements, this.#includeStack);
|
|
181
194
|
console.debug(`[${meta["timestamp"]}] ${formattedMessage}`);
|
|
182
195
|
}
|
|
183
196
|
}
|
|
184
197
|
info(message, ...replacements) {
|
|
185
198
|
if (this.#level <= LOG_LEVELS.info) {
|
|
186
|
-
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements);
|
|
199
|
+
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements, this.#includeStack);
|
|
187
200
|
console.info(`[${meta["timestamp"]}] ${formattedMessage}`);
|
|
188
201
|
}
|
|
189
202
|
}
|
|
190
203
|
warn(message, ...replacements) {
|
|
191
204
|
if (this.#level <= LOG_LEVELS.warn) {
|
|
192
|
-
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements);
|
|
205
|
+
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements, this.#includeStack);
|
|
193
206
|
console.warn(`[${meta["timestamp"]}] ${formattedMessage}`);
|
|
194
207
|
}
|
|
195
208
|
}
|
|
196
209
|
error(message, ...replacements) {
|
|
197
210
|
if (this.#level <= LOG_LEVELS.error) {
|
|
198
|
-
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements);
|
|
211
|
+
const [formattedMessage, meta] = formatMessage(this.#tagString, message, replacements, this.#includeStack);
|
|
199
212
|
console.error(`[${meta["timestamp"]}] ${formattedMessage}`);
|
|
200
213
|
}
|
|
201
214
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#tags","#tagString","#level"],"sources":["../src/state.ts","../src/module.ts","../src/controller.ts","../src/logger.ts"],"sourcesContent":["import type {\n AssertIsDocumentOfType,\n AssertIsStateOfType,\n CreateState,\n DocumentModelDocument,\n DocumentModelGlobalState,\n DocumentModelPHState,\n IsDocumentOfType,\n IsStateOfType,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n assertIsDocumentModelDocument,\n assertIsDocumentModelState,\n baseCreateDocument,\n defaultBaseState,\n documentModelDocumentType,\n documentModelInitialGlobalState,\n documentModelInitialLocalState,\n isDocumentModelDocument,\n isDocumentModelState,\n} from \"@powerhousedao/shared/document-model\";\n\nexport const isStateOfType: IsStateOfType<DocumentModelPHState> = (state) => {\n return isDocumentModelState(state);\n};\n\nexport const assertIsStateOfType: AssertIsStateOfType<DocumentModelPHState> = (\n state,\n) => {\n assertIsDocumentModelState(state);\n};\n\nexport const isDocumentOfType: IsDocumentOfType<DocumentModelPHState> = (\n document,\n) => {\n return isDocumentModelDocument(document);\n};\n\nexport const assertIsDocumentOfType: AssertIsDocumentOfType<\n DocumentModelPHState\n> = (document) => {\n assertIsDocumentModelDocument(document);\n};\nexport const documentModelCreateState: CreateState<DocumentModelPHState> = (\n state,\n) => {\n return {\n ...defaultBaseState(),\n global: {\n ...documentModelInitialGlobalState,\n ...((state?.global ?? {}) as DocumentModelGlobalState),\n },\n local: { ...documentModelInitialLocalState, ...(state?.local ?? {}) },\n };\n};\n\nexport function documentModelCreateDocument(\n state?: Partial<DocumentModelPHState>,\n): DocumentModelDocument {\n const document = baseCreateDocument(documentModelCreateState, state);\n document.header.documentType = documentModelDocumentType;\n\n return document;\n}\n","import type { DocumentModelDocumentModelModule } from \"@powerhousedao/shared/document-model\";\nimport {\n actions,\n createState,\n defaultBaseState,\n documentModelFileExtension,\n documentModelGlobalState,\n documentModelLoadFromInput,\n documentModelReducer,\n documentModelSaveToFileHandle,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n assertIsDocumentOfType,\n assertIsStateOfType,\n documentModelCreateDocument,\n documentModelCreateState,\n isDocumentOfType,\n isStateOfType,\n} from \"./state.js\";\n\nconst utils = {\n fileExtension: documentModelFileExtension,\n createState: documentModelCreateState,\n createDocument: documentModelCreateDocument,\n loadFromInput: documentModelLoadFromInput,\n saveToFileHandle: documentModelSaveToFileHandle,\n isStateOfType,\n assertIsStateOfType,\n isDocumentOfType,\n assertIsDocumentOfType,\n};\n\nexport const documentModelDocumentModelModule: DocumentModelDocumentModelModule =\n {\n reducer: documentModelReducer,\n documentModel: createState(defaultBaseState(), documentModelGlobalState),\n actions,\n utils,\n };\n","import {\n type Action,\n type DocumentAction,\n type DocumentModelAction,\n type DocumentModelModule,\n type DocumentModelPHState,\n type DocumentOperations,\n type Operation,\n type PHBaseState,\n type PHDocument,\n type PHDocumentHeader,\n} from \"@powerhousedao/shared/document-model\";\nimport { documentModelDocumentModelModule } from \"./module.js\";\n\ntype ScreamingSnakeToCamel<S extends string> =\n S extends `${infer Head}_${infer Tail}`\n ? `${Lowercase<Head>}${Capitalize<ScreamingSnakeToCamel<Tail>>}`\n : Lowercase<S>;\n\nexport type DocumentChangeEvent<TState extends PHBaseState = PHBaseState> = {\n document: PHDocument<TState>;\n};\n\nexport type DocumentChangeListener<TState extends PHBaseState = PHBaseState> = (\n event: DocumentChangeEvent<TState>,\n) => void;\n\nexport type ActionMap<TAction extends Action, TReturn = void> = {\n [K in (TAction | DocumentAction)[\"type\"] as ScreamingSnakeToCamel<K>]: (\n input: Extract<TAction | DocumentAction, { type: K }>[\"input\"],\n ) => TReturn & ActionMap<TAction, TReturn>;\n};\n\nexport class PHDocumentController<\n TState extends PHBaseState,\n> implements PHDocument<TState> {\n readonly module: DocumentModelModule<TState>;\n protected _document: PHDocument<TState>;\n private listeners: DocumentChangeListener<TState>[] = [];\n\n constructor(\n module: DocumentModelModule<TState>,\n initialDocument?: PHDocument<TState>,\n ) {\n this.module = module;\n this._document = initialDocument ?? module.utils.createDocument();\n\n // dynamically add action methods to the controller\n for (const actionType in this.module.actions) {\n Object.defineProperty(this, actionType, {\n value: (input: unknown) => {\n const action = this.module.actions[actionType](input);\n this._document = this.module.reducer(this._document, action);\n this.notifyListeners();\n return this;\n },\n });\n }\n }\n\n get document(): PHDocument<TState> {\n return this._document;\n }\n\n get header(): PHDocumentHeader {\n return this.document.header;\n }\n get state(): TState {\n return this.document.state;\n }\n get initialState(): TState {\n return this.document.initialState;\n }\n get operations(): DocumentOperations {\n return this.document.operations;\n }\n get clipboard(): Operation[] {\n return this.document.clipboard;\n }\n\n onChange(listener: DocumentChangeListener<TState>): () => void {\n this.listeners.push(listener);\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener);\n };\n }\n\n private notifyListeners(): void {\n if (this.listeners.length === 0) return;\n const event: DocumentChangeEvent<TState> = { document: this._document };\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n static forDocumentModel<TState extends PHBaseState, TAction extends Action>(\n module: DocumentModelModule<TState>,\n ) {\n return class extends PHDocumentController<TState> {\n constructor(initialDocument?: PHDocument<TState>) {\n super(module, initialDocument);\n }\n } as unknown as new (\n initialDocument?: PHDocument<TState>,\n ) => PHDocumentController<TState> &\n ActionMap<TAction, PHDocumentController<TState>>;\n }\n}\n\nexport const DocumentModelController = PHDocumentController.forDocumentModel<\n DocumentModelPHState,\n DocumentModelAction\n>(documentModelDocumentModelModule);\n","import type { ILogger, LoggerErrorHandler } from \"./logger-types.js\";\n\nconst tokenSub = /@([a-zA-Z0-9_]+)/g;\nconst dtf = new Intl.DateTimeFormat(undefined, {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n fractionalSecondDigits: 2,\n});\n\nconst formatMessage = (\n tagString: string,\n message: string,\n replacements: any[],\n): [string, Record<string, any>] => {\n const meta: Record<string, any> = {};\n const uniqueTokens: string[] = [];\n\n let results;\n while ((results = tokenSub.exec(message)) !== null) {\n const tokenName = results[1];\n const index = uniqueTokens.indexOf(tokenName);\n if (index === -1) {\n uniqueTokens.push(tokenName);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const replacement = replacements[uniqueTokens.length - 1];\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n meta[tokenName] = replacement;\n }\n }\n\n // replace\n for (const [key, value] of Object.entries(meta)) {\n let stringValue;\n if (!value) {\n stringValue = \"null\";\n } else if (typeof value === \"string\") {\n stringValue = value;\n } else if (typeof value === \"object\") {\n stringValue = JSON.stringify(value);\n } else if (typeof value === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const name = (value as Function).name;\n stringValue = name ? `${name}()` : \"anonymous()\";\n } else {\n stringValue = String(value);\n }\n\n message = message.replaceAll(`@${key}`, stringValue);\n }\n\n if (tagString.length > 0) {\n message = `${tagString} ${message}`;\n }\n\n // timestamp\n const now = new Date();\n const timestamp = dtf.format(now);\n meta[\"timestamp\"] = timestamp;\n\n return [message, meta];\n};\n\nconst LOG_LEVELS = {\n verbose: 0,\n debug: 1,\n info: 2,\n warn: 3,\n error: 4,\n} as const;\n\nexport class ConsoleLogger implements ILogger {\n #tags: string[];\n #tagString: string;\n #level: number = LOG_LEVELS.info;\n\n errorHandler: LoggerErrorHandler;\n\n constructor(tags?: string[], handler?: LoggerErrorHandler) {\n this.#tags = tags || [];\n this.#tagString = this.#tags.map((tag) => `[${tag}]`).join(\"\");\n\n this.errorHandler = handler ?? (() => {});\n }\n\n get level(): keyof typeof LOG_LEVELS {\n return Object.keys(LOG_LEVELS).find(\n (key) => LOG_LEVELS[key as keyof typeof LOG_LEVELS] === this.#level,\n ) as keyof typeof LOG_LEVELS;\n }\n\n set level(value: keyof typeof LOG_LEVELS) {\n this.#level = LOG_LEVELS[value];\n }\n\n child(tags: string[]): ILogger {\n const logger = new ConsoleLogger(\n [...this.#tags, ...tags],\n this.errorHandler,\n );\n logger.level = this.level;\n return logger;\n }\n\n verbose(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.verbose) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n );\n\n console.debug(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n debug(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.debug) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n );\n\n console.debug(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n info(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.info) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n );\n\n console.info(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n warn(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.warn) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n );\n\n console.warn(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n error(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.error) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n );\n\n console.error(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n}\n\n// Singleton instance\nexport const logger: ILogger = new ConsoleLogger();\n\n// Global configuration\nexport const setLogLevel = (level: ILogger[\"level\"]) => {\n logger.level = level;\n};\n\nexport const setErrorHandler = (handler: LoggerErrorHandler) => {\n logger.errorHandler = handler;\n};\n\n// Backwards-compatible factory function\nexport const childLogger = (tags: string[]): ILogger => {\n return logger.child(tags);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#tags","#tagString","#level","#includeStack"],"sources":["../src/state.ts","../src/module.ts","../src/controller.ts","../src/logger.ts"],"sourcesContent":["import type {\n AssertIsDocumentOfType,\n AssertIsStateOfType,\n CreateState,\n DocumentModelDocument,\n DocumentModelGlobalState,\n DocumentModelPHState,\n IsDocumentOfType,\n IsStateOfType,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n assertIsDocumentModelDocument,\n assertIsDocumentModelState,\n baseCreateDocument,\n defaultBaseState,\n documentModelDocumentType,\n documentModelInitialGlobalState,\n documentModelInitialLocalState,\n isDocumentModelDocument,\n isDocumentModelState,\n} from \"@powerhousedao/shared/document-model\";\n\nexport const isStateOfType: IsStateOfType<DocumentModelPHState> = (state) => {\n return isDocumentModelState(state);\n};\n\nexport const assertIsStateOfType: AssertIsStateOfType<DocumentModelPHState> = (\n state,\n) => {\n assertIsDocumentModelState(state);\n};\n\nexport const isDocumentOfType: IsDocumentOfType<DocumentModelPHState> = (\n document,\n) => {\n return isDocumentModelDocument(document);\n};\n\nexport const assertIsDocumentOfType: AssertIsDocumentOfType<\n DocumentModelPHState\n> = (document) => {\n assertIsDocumentModelDocument(document);\n};\nexport const documentModelCreateState: CreateState<DocumentModelPHState> = (\n state,\n) => {\n return {\n ...defaultBaseState(),\n global: {\n ...documentModelInitialGlobalState,\n ...((state?.global ?? {}) as DocumentModelGlobalState),\n },\n local: { ...documentModelInitialLocalState, ...(state?.local ?? {}) },\n };\n};\n\nexport function documentModelCreateDocument(\n state?: Partial<DocumentModelPHState>,\n): DocumentModelDocument {\n const document = baseCreateDocument(documentModelCreateState, state);\n document.header.documentType = documentModelDocumentType;\n\n return document;\n}\n","import type { DocumentModelDocumentModelModule } from \"@powerhousedao/shared/document-model\";\nimport {\n actions,\n createState,\n defaultBaseState,\n documentModelFileExtension,\n documentModelGlobalState,\n documentModelLoadFromInput,\n documentModelReducer,\n documentModelSaveToFileHandle,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n assertIsDocumentOfType,\n assertIsStateOfType,\n documentModelCreateDocument,\n documentModelCreateState,\n isDocumentOfType,\n isStateOfType,\n} from \"./state.js\";\n\nconst utils = {\n fileExtension: documentModelFileExtension,\n createState: documentModelCreateState,\n createDocument: documentModelCreateDocument,\n loadFromInput: documentModelLoadFromInput,\n saveToFileHandle: documentModelSaveToFileHandle,\n isStateOfType,\n assertIsStateOfType,\n isDocumentOfType,\n assertIsDocumentOfType,\n};\n\nexport const documentModelDocumentModelModule: DocumentModelDocumentModelModule =\n {\n reducer: documentModelReducer,\n documentModel: createState(defaultBaseState(), documentModelGlobalState),\n actions,\n utils,\n };\n","import {\n type Action,\n type DocumentAction,\n type DocumentModelAction,\n type DocumentModelModule,\n type DocumentModelPHState,\n type DocumentOperations,\n type Operation,\n type PHBaseState,\n type PHDocument,\n type PHDocumentHeader,\n} from \"@powerhousedao/shared/document-model\";\nimport { documentModelDocumentModelModule } from \"./module.js\";\n\ntype ScreamingSnakeToCamel<S extends string> =\n S extends `${infer Head}_${infer Tail}`\n ? `${Lowercase<Head>}${Capitalize<ScreamingSnakeToCamel<Tail>>}`\n : Lowercase<S>;\n\nexport type DocumentChangeEvent<TState extends PHBaseState = PHBaseState> = {\n document: PHDocument<TState>;\n};\n\nexport type DocumentChangeListener<TState extends PHBaseState = PHBaseState> = (\n event: DocumentChangeEvent<TState>,\n) => void;\n\nexport type ActionMap<TAction extends Action, TReturn = void> = {\n [K in (TAction | DocumentAction)[\"type\"] as ScreamingSnakeToCamel<K>]: (\n input: Extract<TAction | DocumentAction, { type: K }>[\"input\"],\n ) => TReturn & ActionMap<TAction, TReturn>;\n};\n\nexport class PHDocumentController<\n TState extends PHBaseState,\n> implements PHDocument<TState> {\n readonly module: DocumentModelModule<TState>;\n protected _document: PHDocument<TState>;\n private listeners: DocumentChangeListener<TState>[] = [];\n\n constructor(\n module: DocumentModelModule<TState>,\n initialDocument?: PHDocument<TState>,\n ) {\n this.module = module;\n this._document = initialDocument ?? module.utils.createDocument();\n\n // dynamically add action methods to the controller\n for (const actionType in this.module.actions) {\n Object.defineProperty(this, actionType, {\n value: (input: unknown) => {\n const action = this.module.actions[actionType](input);\n this._document = this.module.reducer(this._document, action);\n this.notifyListeners();\n return this;\n },\n });\n }\n }\n\n get document(): PHDocument<TState> {\n return this._document;\n }\n\n get header(): PHDocumentHeader {\n return this.document.header;\n }\n get state(): TState {\n return this.document.state;\n }\n get initialState(): TState {\n return this.document.initialState;\n }\n get operations(): DocumentOperations {\n return this.document.operations;\n }\n get clipboard(): Operation[] {\n return this.document.clipboard;\n }\n\n onChange(listener: DocumentChangeListener<TState>): () => void {\n this.listeners.push(listener);\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener);\n };\n }\n\n private notifyListeners(): void {\n if (this.listeners.length === 0) return;\n const event: DocumentChangeEvent<TState> = { document: this._document };\n for (const listener of this.listeners) {\n listener(event);\n }\n }\n\n static forDocumentModel<TState extends PHBaseState, TAction extends Action>(\n module: DocumentModelModule<TState>,\n ) {\n return class extends PHDocumentController<TState> {\n constructor(initialDocument?: PHDocument<TState>) {\n super(module, initialDocument);\n }\n } as unknown as new (\n initialDocument?: PHDocument<TState>,\n ) => PHDocumentController<TState> &\n ActionMap<TAction, PHDocumentController<TState>>;\n }\n}\n\nexport const DocumentModelController = PHDocumentController.forDocumentModel<\n DocumentModelPHState,\n DocumentModelAction\n>(documentModelDocumentModelModule);\n","import type { ILogger, LoggerErrorHandler } from \"./logger-types.js\";\n\nconst tokenSub = /@([a-zA-Z0-9_]+)/g;\nconst dtf = new Intl.DateTimeFormat(undefined, {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n fractionalSecondDigits: 2,\n});\n\nconst stringify = (value: unknown, includeStack: boolean): string => {\n if (value === null || value === undefined) return \"null\";\n if (typeof value === \"string\") return value;\n if (value instanceof Error) {\n const base = `${value.name}: ${value.message}`;\n return includeStack && value.stack ? `${base}\\n${value.stack}` : base;\n }\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n if (typeof value === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const name = (value as Function).name;\n return name ? `${name}()` : \"anonymous()\";\n }\n return String(value);\n};\n\nconst formatMessage = (\n tagString: string,\n message: string,\n replacements: any[],\n includeStack: boolean,\n): [string, Record<string, any>] => {\n const meta: Record<string, any> = {};\n const uniqueTokens: string[] = [];\n\n let results;\n while ((results = tokenSub.exec(message)) !== null) {\n const tokenName = results[1];\n const index = uniqueTokens.indexOf(tokenName);\n if (index === -1) {\n uniqueTokens.push(tokenName);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const replacement = replacements[uniqueTokens.length - 1];\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n meta[tokenName] = replacement;\n }\n }\n\n // replace\n for (const [key, value] of Object.entries(meta)) {\n message = message.replaceAll(`@${key}`, stringify(value, includeStack));\n }\n\n // Any replacements past the unique-token count would otherwise be\n // silently dropped — append them so positional Errors still surface.\n const extras = replacements.slice(uniqueTokens.length);\n if (extras.length > 0) {\n message = `${message} ${extras.map((v) => stringify(v, includeStack)).join(\" \")}`;\n }\n\n if (tagString.length > 0) {\n message = `${tagString} ${message}`;\n }\n\n // timestamp\n const now = new Date();\n const timestamp = dtf.format(now);\n meta[\"timestamp\"] = timestamp;\n\n return [message, meta];\n};\n\nconst LOG_LEVELS = {\n verbose: 0,\n debug: 1,\n info: 2,\n warn: 3,\n error: 4,\n} as const;\n\nexport class ConsoleLogger implements ILogger {\n #tags: string[];\n #tagString: string;\n #level: number = LOG_LEVELS.info;\n\n errorHandler: LoggerErrorHandler;\n\n constructor(tags?: string[], handler?: LoggerErrorHandler) {\n this.#tags = tags || [];\n this.#tagString = this.#tags.map((tag) => `[${tag}]`).join(\"\");\n\n this.errorHandler = handler ?? (() => {});\n }\n\n get level(): keyof typeof LOG_LEVELS {\n return Object.keys(LOG_LEVELS).find(\n (key) => LOG_LEVELS[key as keyof typeof LOG_LEVELS] === this.#level,\n ) as keyof typeof LOG_LEVELS;\n }\n\n set level(value: keyof typeof LOG_LEVELS) {\n this.#level = LOG_LEVELS[value];\n }\n\n child(tags: string[]): ILogger {\n const logger = new ConsoleLogger(\n [...this.#tags, ...tags],\n this.errorHandler,\n );\n logger.level = this.level;\n return logger;\n }\n\n // Errors get full stacks only at debug/verbose; at info/warn/error we\n // emit `name: message` to keep production logs readable.\n get #includeStack(): boolean {\n return this.#level <= LOG_LEVELS.debug;\n }\n\n verbose(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.verbose) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n this.#includeStack,\n );\n\n console.debug(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n debug(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.debug) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n this.#includeStack,\n );\n\n console.debug(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n info(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.info) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n this.#includeStack,\n );\n\n console.info(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n warn(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.warn) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n this.#includeStack,\n );\n\n console.warn(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n\n error(message: string, ...replacements: any[]): void {\n if (this.#level <= LOG_LEVELS.error) {\n const [formattedMessage, meta] = formatMessage(\n this.#tagString,\n message,\n replacements,\n this.#includeStack,\n );\n\n console.error(`[${meta[\"timestamp\"]}] ${formattedMessage}`);\n }\n }\n}\n\n// Singleton instance\nexport const logger: ILogger = new ConsoleLogger();\n\n// Global configuration\nexport const setLogLevel = (level: ILogger[\"level\"]) => {\n logger.level = level;\n};\n\nexport const setErrorHandler = (handler: LoggerErrorHandler) => {\n logger.errorHandler = handler;\n};\n\n// Backwards-compatible factory function\nexport const childLogger = (tags: string[]): ILogger => {\n return logger.child(tags);\n};\n"],"mappings":"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"}
|
package/dist/node.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.mts","names":[],"sources":["../node.mts"],"mappings":";;;;;;AAgCA;;;iBAAsB,YAAA,CAAa,IAAA,WAAe,OAAA,CAAQ,eAAA;;;;;;iBAapC,aAAA,CAAc,GAAA,WAAc,OAAA,CAAQ,eAAA;AAAA,iBAa1C,aAAA,CACd,IAAA,UACA,IAAA,UACA,IAAA,EAAM,UAAA,GACL,OAAA;AAAA,iBAuBa,YAAA,CAAa,IAAA,WAAY,eAAA;AAAA,iBAIzB,aAAA,CACd,GAAA,WACC,OAAA;EAAU,MAAA,EAAQ,MAAA;EAAQ,QAAA;AAAA;AAAA,cAoBhB,WAAA,GAAqB,IAAA,aAAY,OAAA,CAAA,eAAA;AAAA,cAIjC,QAAA,GACX,IAAA,EAAM,UAAA,EACN,SAAA,WACA,QAAA,qBACA,OAAA,GAAU,MAAA;AA7DZ;;;;;;;;;;;AA2BA;;;;AA3BA,iBA6FsB,gBAAA,gBACL,WAAA,GAAc,WAAA,CAAA,CAE7B,IAAA,UACA,OAAA,EAAS,OAAA,CAAQ,MAAA,GACjB,OAAA,GAAU,qBAAA,GACT,OAAA,CAAQ,UAAA,CAAW,MAAA;AApEtB;;;;;AAAA,iBA8EsB,qBAAA,CACpB,IAAA,EAAM,iBAAA,EACN,IAAA,UACA,SAAA,WAAiB,OAAA;;;;;;AA3DnB;;;;;;;
|
|
1
|
+
{"version":3,"file":"node.d.mts","names":[],"sources":["../node.mts"],"mappings":";;;;;;AAgCA;;;iBAAsB,YAAA,CAAa,IAAA,WAAe,OAAA,CAAQ,eAAA;;;;;;iBAapC,aAAA,CAAc,GAAA,WAAc,OAAA,CAAQ,eAAA;AAAA,iBAa1C,aAAA,CACd,IAAA,UACA,IAAA,UACA,IAAA,EAAM,UAAA,GACL,OAAA;AAAA,iBAuBa,YAAA,CAAa,IAAA,WAAY,eAAA;AAAA,iBAIzB,aAAA,CACd,GAAA,WACC,OAAA;EAAU,MAAA,EAAQ,MAAA;EAAQ,QAAA;AAAA;AAAA,cAoBhB,WAAA,GAAqB,IAAA,aAAY,OAAA,CAAA,eAAA;AAAA,cAIjC,QAAA,GACX,IAAA,EAAM,UAAA,EACN,SAAA,WACA,QAAA,qBACA,OAAA,GAAU,MAAA;AA7DZ;;;;;;;;;;;AA2BA;;;;AA3BA,iBA6FsB,gBAAA,gBACL,WAAA,GAAc,WAAA,CAAA,CAE7B,IAAA,UACA,OAAA,EAAS,OAAA,CAAQ,MAAA,GACjB,OAAA,GAAU,qBAAA,GACT,OAAA,CAAQ,UAAA,CAAW,MAAA;AApEtB;;;;;AAAA,iBA8EsB,qBAAA,CACpB,IAAA,EAAM,iBAAA,EACN,IAAA,UACA,SAAA,WAAiB,OAAA;;;;;;AA3DnB;;;;;;;iBAqFsB,cAAA,CACpB,QAAA,EAAU,UAAA,EACV,IAAA,UACA,SAAA,UACA,IAAA,YAAa,OAAA"}
|
package/dist/node.mjs
CHANGED
|
@@ -117,10 +117,7 @@ async function baseLoadFromFile(path, reducer, options) {
|
|
|
117
117
|
* Creates a file with minimal header and empty operations.
|
|
118
118
|
*/
|
|
119
119
|
async function baseMinimalSaveToFile(data, path, extension) {
|
|
120
|
-
const file = await
|
|
121
|
-
type: "uint8array",
|
|
122
|
-
streamFiles: true
|
|
123
|
-
});
|
|
120
|
+
const file = await createMinimalZip(data);
|
|
124
121
|
const fileExtension = extension ? `.${extension}.phd` : ".phd";
|
|
125
122
|
return writeFileNode(path, data.name.endsWith(fileExtension) ? data.name : `${data.name}${fileExtension}`, file);
|
|
126
123
|
}
|
|
@@ -137,10 +134,7 @@ async function baseMinimalSaveToFile(data, path, extension) {
|
|
|
137
134
|
* @returns A promise that resolves to the path of the saved file.
|
|
138
135
|
*/
|
|
139
136
|
async function baseSaveToFile(document, path, extension, name) {
|
|
140
|
-
const file = await
|
|
141
|
-
type: "uint8array",
|
|
142
|
-
streamFiles: true
|
|
143
|
-
});
|
|
137
|
+
const file = await createZip(document);
|
|
144
138
|
const fileName = name ?? document.header.name;
|
|
145
139
|
const fileExtension = extension ? `.${extension}.phd` : ".phd";
|
|
146
140
|
return writeFileNode(path, fileName.endsWith(fileExtension) ? fileName : `${fileName}${fileExtension}`, file);
|
package/dist/node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.mjs","names":[],"sources":["../node.mts"],"sourcesContent":["import {\n baseLoadFromInput,\n createMinimalZip,\n createZip,\n type Attachment,\n type AttachmentInput,\n type MinimalBackupData,\n type PHBaseState,\n type PHDocument,\n type Reducer,\n type ReplayDocumentOptions,\n} from \"@powerhousedao/shared/document-model\";\nimport mime from \"mime/lite\";\nimport type { BinaryLike } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport https from \"node:https\";\nimport { join } from \"node:path\";\n\nfunction getFileAttributes(\n file: string,\n): Omit<Attachment, \"data\" | \"mimeType\"> {\n const extension = file.replace(/^.*\\./, \"\") || undefined;\n const fileName = file.replace(/^.*[/\\\\]/, \"\") || undefined;\n return { extension, fileName };\n}\n\n/**\n * Reads an attachment from a file and returns its base64-encoded data and MIME type.\n * @param path - The path of the attachment file to read.\n * @returns A Promise that resolves to an object containing the base64-encoded data and MIME type of the attachment.\n */\nexport async function getLocalFile(path: string): Promise<AttachmentInput> {\n const buffer = await getFileNode(path);\n const mimeType = mime.getType(path) || \"application/octet-stream\";\n const attributes = getFileAttributes(path);\n const data = buffer.toString(\"base64\");\n return { data, hash: hashNode(data), mimeType, ...attributes };\n}\n\n/**\n * Fetches an attachment from a URL and returns its base64-encoded data and MIME type.\n * @param url - The URL of the attachment to fetch.\n * @returns A Promise that resolves to an object containing the base64-encoded data and MIME type of the attachment.\n */\nexport async function getRemoteFile(url: string): Promise<AttachmentInput> {\n const { buffer, mimeType = \"application/octet-stream\" } =\n await fetchFileNode(url);\n const attributes = getFileAttributes(url);\n const data = buffer.toString(\"base64\");\n return {\n data,\n hash: hashNode(data),\n mimeType,\n ...attributes,\n };\n}\n\nexport function writeFileNode(\n path: string,\n name: string,\n data: Uint8Array,\n): Promise<string> {\n const filePath = join(path, name);\n fs.mkdirSync(path, { recursive: true });\n\n return new Promise((resolve, reject) => {\n try {\n fs.writeFile(filePath, data, {}, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve(filePath);\n }\n });\n } catch (error: unknown) {\n if (error instanceof Error) {\n reject(error);\n } else {\n reject(new Error(String(error)));\n }\n }\n });\n}\n\nexport function readFileNode(path: string) {\n return fs.readFileSync(path);\n}\n\nexport function fetchFileNode(\n url: string,\n): Promise<{ buffer: Buffer; mimeType?: string }> {\n return new Promise((resolve, reject) => {\n https\n .get(url, (resp) => {\n const data: Uint8Array[] = [];\n const mimeType = resp.headers[\"content-type\"];\n resp.on(\"data\", (chunk: Uint8Array) => {\n data.push(chunk);\n });\n\n resp.on(\"end\", () => {\n resolve({ buffer: Buffer.concat(data), mimeType });\n });\n })\n .on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\nexport const getFileNode = async (file: string) => {\n return readFileNode(file);\n};\n\nexport const hashNode = (\n data: BinaryLike,\n algorithm = \"sha1\",\n encoding: \"base64\" | \"hex\" = \"base64\",\n _params?: Record<string, unknown>,\n) => {\n if (![\"sha1\", \"sha256\", \"sha512\"].includes(algorithm)) {\n throw new Error(\n `Hashing algorithm not supported: \"${algorithm}\". Available: sha1, sha256, sha512`,\n );\n }\n\n if (![\"base64\", \"hex\"].includes(encoding)) {\n throw new Error(\n `Hash encoding not supported: \"${encoding}\". Available: base64, hex`,\n );\n }\n\n return createHash(algorithm).update(data).digest(encoding);\n};\n\n/**\n * Loads a document from a ZIP file.\n *\n * @remarks\n * This function reads a ZIP file and returns the document state after\n * applying all the operations. The reducer is used to apply the operations.\n *\n * @typeParam S - The type of the state object.\n * @typeParam A - The type of the actions that can be applied to the state object.\n *\n * @param path - The path to the ZIP file.\n * @param reducer - The reducer to apply the operations to the state object.\n * @returns A promise that resolves to the document state after applying all the operations.\n * @throws An error if the initial state or the operations history is not found in the ZIP file.\n */\nexport async function baseLoadFromFile<\n TState extends PHBaseState = PHBaseState,\n>(\n path: string,\n reducer: Reducer<TState>,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const file = readFileNode(path);\n return baseLoadFromInput(file, reducer, options);\n}\n\n/**\n * Saves a minimal document backup to a .phd file.\n * Used when the full document is not available (e.g., in onOperations handler).\n * Creates a file with minimal header and empty operations.\n */\nexport async function baseMinimalSaveToFile(\n data: MinimalBackupData,\n path: string,\n extension: string,\n) {\n const
|
|
1
|
+
{"version":3,"file":"node.mjs","names":[],"sources":["../node.mts"],"sourcesContent":["import {\n baseLoadFromInput,\n createMinimalZip,\n createZip,\n type Attachment,\n type AttachmentInput,\n type MinimalBackupData,\n type PHBaseState,\n type PHDocument,\n type Reducer,\n type ReplayDocumentOptions,\n} from \"@powerhousedao/shared/document-model\";\nimport mime from \"mime/lite\";\nimport type { BinaryLike } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\nimport fs from \"node:fs\";\nimport https from \"node:https\";\nimport { join } from \"node:path\";\n\nfunction getFileAttributes(\n file: string,\n): Omit<Attachment, \"data\" | \"mimeType\"> {\n const extension = file.replace(/^.*\\./, \"\") || undefined;\n const fileName = file.replace(/^.*[/\\\\]/, \"\") || undefined;\n return { extension, fileName };\n}\n\n/**\n * Reads an attachment from a file and returns its base64-encoded data and MIME type.\n * @param path - The path of the attachment file to read.\n * @returns A Promise that resolves to an object containing the base64-encoded data and MIME type of the attachment.\n */\nexport async function getLocalFile(path: string): Promise<AttachmentInput> {\n const buffer = await getFileNode(path);\n const mimeType = mime.getType(path) || \"application/octet-stream\";\n const attributes = getFileAttributes(path);\n const data = buffer.toString(\"base64\");\n return { data, hash: hashNode(data), mimeType, ...attributes };\n}\n\n/**\n * Fetches an attachment from a URL and returns its base64-encoded data and MIME type.\n * @param url - The URL of the attachment to fetch.\n * @returns A Promise that resolves to an object containing the base64-encoded data and MIME type of the attachment.\n */\nexport async function getRemoteFile(url: string): Promise<AttachmentInput> {\n const { buffer, mimeType = \"application/octet-stream\" } =\n await fetchFileNode(url);\n const attributes = getFileAttributes(url);\n const data = buffer.toString(\"base64\");\n return {\n data,\n hash: hashNode(data),\n mimeType,\n ...attributes,\n };\n}\n\nexport function writeFileNode(\n path: string,\n name: string,\n data: Uint8Array,\n): Promise<string> {\n const filePath = join(path, name);\n fs.mkdirSync(path, { recursive: true });\n\n return new Promise((resolve, reject) => {\n try {\n fs.writeFile(filePath, data, {}, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve(filePath);\n }\n });\n } catch (error: unknown) {\n if (error instanceof Error) {\n reject(error);\n } else {\n reject(new Error(String(error)));\n }\n }\n });\n}\n\nexport function readFileNode(path: string) {\n return fs.readFileSync(path);\n}\n\nexport function fetchFileNode(\n url: string,\n): Promise<{ buffer: Buffer; mimeType?: string }> {\n return new Promise((resolve, reject) => {\n https\n .get(url, (resp) => {\n const data: Uint8Array[] = [];\n const mimeType = resp.headers[\"content-type\"];\n resp.on(\"data\", (chunk: Uint8Array) => {\n data.push(chunk);\n });\n\n resp.on(\"end\", () => {\n resolve({ buffer: Buffer.concat(data), mimeType });\n });\n })\n .on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\nexport const getFileNode = async (file: string) => {\n return readFileNode(file);\n};\n\nexport const hashNode = (\n data: BinaryLike,\n algorithm = \"sha1\",\n encoding: \"base64\" | \"hex\" = \"base64\",\n _params?: Record<string, unknown>,\n) => {\n if (![\"sha1\", \"sha256\", \"sha512\"].includes(algorithm)) {\n throw new Error(\n `Hashing algorithm not supported: \"${algorithm}\". Available: sha1, sha256, sha512`,\n );\n }\n\n if (![\"base64\", \"hex\"].includes(encoding)) {\n throw new Error(\n `Hash encoding not supported: \"${encoding}\". Available: base64, hex`,\n );\n }\n\n return createHash(algorithm).update(data).digest(encoding);\n};\n\n/**\n * Loads a document from a ZIP file.\n *\n * @remarks\n * This function reads a ZIP file and returns the document state after\n * applying all the operations. The reducer is used to apply the operations.\n *\n * @typeParam S - The type of the state object.\n * @typeParam A - The type of the actions that can be applied to the state object.\n *\n * @param path - The path to the ZIP file.\n * @param reducer - The reducer to apply the operations to the state object.\n * @returns A promise that resolves to the document state after applying all the operations.\n * @throws An error if the initial state or the operations history is not found in the ZIP file.\n */\nexport async function baseLoadFromFile<\n TState extends PHBaseState = PHBaseState,\n>(\n path: string,\n reducer: Reducer<TState>,\n options?: ReplayDocumentOptions,\n): Promise<PHDocument<TState>> {\n const file = readFileNode(path);\n return baseLoadFromInput(file, reducer, options);\n}\n\n/**\n * Saves a minimal document backup to a .phd file.\n * Used when the full document is not available (e.g., in onOperations handler).\n * Creates a file with minimal header and empty operations.\n */\nexport async function baseMinimalSaveToFile(\n data: MinimalBackupData,\n path: string,\n extension: string,\n) {\n const file = await createMinimalZip(data);\n const fileExtension = extension ? `.${extension}.phd` : \".phd\";\n\n return writeFileNode(\n path,\n data.name.endsWith(fileExtension)\n ? data.name\n : `${data.name}${fileExtension}`,\n file,\n );\n}\n\n/**\n * Saves a document to a ZIP file.\n *\n * @remarks\n * This function creates a ZIP file containing the document's state, operations,\n * and file attachments. The file is saved to the specified path.\n *\n * @param document - The document to save to the file.\n * @param path - The path to save the file to.\n * @param extension - The extension to use for the file.\n * @returns A promise that resolves to the path of the saved file.\n */\nexport async function baseSaveToFile(\n document: PHDocument,\n path: string,\n extension: string,\n name?: string,\n) {\n const file = await createZip(document);\n const fileName = name ?? document.header.name;\n const fileExtension = extension ? `.${extension}.phd` : \".phd\";\n\n return writeFileNode(\n path,\n fileName.endsWith(fileExtension) ? fileName : `${fileName}${fileExtension}`,\n file,\n );\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "document-model",
|
|
3
|
-
"version": "6.0
|
|
3
|
+
"version": "6.1.0-dev.0",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -13,18 +13,22 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": {
|
|
16
|
+
"source": "./index.ts",
|
|
16
17
|
"import": "./dist/index.js",
|
|
17
18
|
"types": "./dist/index.d.ts"
|
|
18
19
|
},
|
|
19
20
|
"./test": {
|
|
21
|
+
"source": "./test/index.ts",
|
|
20
22
|
"import": "./dist/test/index.js",
|
|
21
23
|
"types": "./dist/test/index.d.ts"
|
|
22
24
|
},
|
|
23
25
|
"./node": {
|
|
26
|
+
"source": "./node.mts",
|
|
24
27
|
"node": "./dist/node.mjs",
|
|
25
28
|
"types": "./dist/node.d.mts"
|
|
26
29
|
},
|
|
27
30
|
"./core": {
|
|
31
|
+
"source": "./index.ts",
|
|
28
32
|
"import": "./dist/index.js",
|
|
29
33
|
"types": "./dist/index.d.ts"
|
|
30
34
|
}
|
|
@@ -34,18 +38,18 @@
|
|
|
34
38
|
"@types/jest": "^29.5.14",
|
|
35
39
|
"@types/mime": "^4.0.0",
|
|
36
40
|
"@types/node": "25.2.3",
|
|
41
|
+
"change-case": "5.4.4",
|
|
37
42
|
"jest": "^30.0.5",
|
|
43
|
+
"mutative": "^1.0.5",
|
|
38
44
|
"tsdown": "0.21.1",
|
|
39
45
|
"tsx": "4.21.0",
|
|
40
|
-
"vitest": "4.1.1"
|
|
46
|
+
"vitest": "4.1.1",
|
|
47
|
+
"zod": "4.3.6"
|
|
41
48
|
},
|
|
42
49
|
"dependencies": {
|
|
43
|
-
"change-case": "5.4.4",
|
|
44
|
-
"mime": "^4.0.4",
|
|
45
|
-
"mutative": "^1.0.5",
|
|
46
|
-
"zod": "4.3.6",
|
|
47
50
|
"jszip": "^3.10.1",
|
|
48
|
-
"
|
|
51
|
+
"mime": "^4.0.4",
|
|
52
|
+
"@powerhousedao/shared": "6.1.0-dev.0"
|
|
49
53
|
},
|
|
50
54
|
"scripts": {
|
|
51
55
|
"tsc": "tsc",
|