@powerhousedao/reactor-attachments 6.2.3-dev.5 → 6.2.3-dev.51

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.
@@ -0,0 +1,262 @@
1
+ import { a as parseRef } from "./switchboard-attachment-transport-BH3ZAmxE.js";
2
+ import { generatorTypeDefs } from "@powerhousedao/document-engineering/graphql";
3
+ import { constantCase, pascalCase } from "change-case";
4
+ import { Kind, buildASTSchema, getNamedType, isInputObjectType, isListType, isNonNullType, parse, print } from "graphql";
5
+ //#region src/reference-index/attachment-schema-compiler.ts
6
+ const ATTACHMENT_REF_TYPE = "AttachmentRef";
7
+ const CODEGEN_SCALAR_NAMES = /* @__PURE__ */ new Set([
8
+ "Unknown",
9
+ "DateTime",
10
+ "Address",
11
+ ATTACHMENT_REF_TYPE,
12
+ ...Object.keys(generatorTypeDefs)
13
+ ]);
14
+ function describeContext(context) {
15
+ return `document type "${context.documentType}", version ${context.version}, action "${context.actionType}"`;
16
+ }
17
+ function compilationError(context, reason) {
18
+ return /* @__PURE__ */ new Error(`Attachment schema compilation failed for ${describeContext(context)}: ${reason}`);
19
+ }
20
+ function extractionError(context, path, reason) {
21
+ return /* @__PURE__ */ new Error(`Attachment extraction failed for ${describeContext(context)} at ${path}: ${reason}`);
22
+ }
23
+ function applicableSpecification(module, context) {
24
+ const matches = module.documentModel.global.specifications.filter((specification) => specification.version === context.version);
25
+ if (matches.length !== 1) throw compilationError(context, matches.length === 0 ? "the module has no matching specification" : "the module has multiple matching specifications");
26
+ return matches[0];
27
+ }
28
+ function parseOperations(specification, context) {
29
+ return specification.modules.flatMap((moduleSpecification) => moduleSpecification.operations.map((operation) => {
30
+ if (operation.schema === null) return {
31
+ document: null,
32
+ operation
33
+ };
34
+ try {
35
+ return {
36
+ document: parse(operation.schema),
37
+ operation
38
+ };
39
+ } catch {
40
+ throw compilationError(context, "an operation has invalid GraphQL SDL");
41
+ }
42
+ }));
43
+ }
44
+ function selectOperation(operations, context) {
45
+ const matches = operations.filter(({ operation }) => operation.name !== null && constantCase(operation.name) === context.actionType);
46
+ if (matches.length > 1) throw compilationError(context, "multiple operations map to the action");
47
+ if (matches.length === 0) return null;
48
+ return matches[0];
49
+ }
50
+ function buildEffectiveSchema(specification, context) {
51
+ const scalarSchemas = Array.from(CODEGEN_SCALAR_NAMES, (name) => `scalar ${name}`);
52
+ const stateSchemas = Object.values(specification.state).map((state) => state.schema);
53
+ const operationSchemas = specification.modules.flatMap((moduleSpecification) => moduleSpecification.operations.flatMap((operation) => operation.schema === null ? [] : [operation.schema]));
54
+ try {
55
+ const document = parse([
56
+ ...scalarSchemas,
57
+ ...stateSchemas,
58
+ ...operationSchemas
59
+ ].filter(Boolean).join("\n\n"));
60
+ return buildASTSchema(dedupeTypeDefinitions(document));
61
+ } catch {
62
+ throw compilationError(context, "the effective GraphQL schema is invalid");
63
+ }
64
+ }
65
+ function dedupeTypeDefinitions(document) {
66
+ const seen = /* @__PURE__ */ new Map();
67
+ const definitions = document.definitions.filter((definition) => {
68
+ if (!("name" in definition) || definition.name?.value === void 0 || definition.kind === Kind.SCALAR_TYPE_DEFINITION) return true;
69
+ const name = definition.name.value;
70
+ const printed = print(definition);
71
+ const existing = seen.get(name);
72
+ if (existing === void 0) {
73
+ seen.set(name, printed);
74
+ return true;
75
+ }
76
+ return existing !== printed;
77
+ });
78
+ return {
79
+ ...document,
80
+ definitions
81
+ };
82
+ }
83
+ function attachmentReachableTypes(definitions) {
84
+ const reachable = /* @__PURE__ */ new Set();
85
+ let changed = true;
86
+ while (changed) {
87
+ changed = false;
88
+ for (const [name, definition] of definitions) {
89
+ if (reachable.has(name)) continue;
90
+ if (Object.values(definition.getFields()).some((field) => {
91
+ const typeName = getNamedType(field.type).name;
92
+ return typeName === ATTACHMENT_REF_TYPE || definitions.has(typeName) && reachable.has(typeName);
93
+ })) {
94
+ reachable.add(name);
95
+ changed = true;
96
+ }
97
+ }
98
+ }
99
+ return reachable;
100
+ }
101
+ function compileValuePlan(type, objectPlans) {
102
+ if (isNonNullType(type)) return {
103
+ ...compileValuePlan(type.ofType, objectPlans),
104
+ required: true
105
+ };
106
+ if (isListType(type)) return {
107
+ item: compileValuePlan(type.ofType, objectPlans),
108
+ kind: "list",
109
+ required: false
110
+ };
111
+ const typeName = type.name;
112
+ if (typeName === ATTACHMENT_REF_TYPE) return {
113
+ kind: "attachment",
114
+ required: false
115
+ };
116
+ const body = objectPlans.get(typeName);
117
+ if (!body) throw new Error(`Internal attachment schema plan error for ${typeName}`);
118
+ return {
119
+ body,
120
+ kind: "object",
121
+ required: false
122
+ };
123
+ }
124
+ function compileRootPlan(rootName, definitions) {
125
+ const reachable = attachmentReachableTypes(definitions);
126
+ if (!reachable.has(rootName)) return null;
127
+ const objectPlans = /* @__PURE__ */ new Map();
128
+ for (const name of reachable) objectPlans.set(name, { fields: [] });
129
+ for (const name of reachable) {
130
+ const definition = definitions.get(name);
131
+ const body = objectPlans.get(name);
132
+ if (!definition || !body) continue;
133
+ for (const field of Object.values(definition.getFields())) {
134
+ const typeName = getNamedType(field.type).name;
135
+ if (typeName !== ATTACHMENT_REF_TYPE && !reachable.has(typeName)) continue;
136
+ body.fields.push({
137
+ hasDefault: field.defaultValue !== void 0,
138
+ name: field.name,
139
+ value: compileValuePlan(field.type, objectPlans)
140
+ });
141
+ }
142
+ }
143
+ return objectPlans.get(rootName) ?? null;
144
+ }
145
+ function readOwnField(value, fieldName, context, path) {
146
+ try {
147
+ if (!Object.prototype.hasOwnProperty.call(value, fieldName)) return {
148
+ present: false,
149
+ value: void 0
150
+ };
151
+ return {
152
+ present: true,
153
+ value: value[fieldName]
154
+ };
155
+ } catch {
156
+ throw extractionError(context, path, "the declared field cannot be read");
157
+ }
158
+ }
159
+ function extractValue(plan, value, path, context, refs, seenRefs, activeObjects) {
160
+ if (value === null || value === void 0) {
161
+ if (plan.required) throw extractionError(context, path, "a required value is missing or null");
162
+ return;
163
+ }
164
+ if (plan.kind === "attachment") {
165
+ if (typeof value !== "string") throw extractionError(context, path, "expected an AttachmentRef string");
166
+ try {
167
+ parseRef(value);
168
+ } catch {
169
+ throw extractionError(context, path, "the AttachmentRef is malformed");
170
+ }
171
+ if (!seenRefs.has(value)) {
172
+ seenRefs.add(value);
173
+ refs.push(value);
174
+ }
175
+ return;
176
+ }
177
+ if (plan.kind === "list") {
178
+ if (!Array.isArray(value)) throw extractionError(context, path, "expected a list");
179
+ for (let index = 0; index < value.length; index += 1) extractValue(plan.item, value[index], `${path}[${index}]`, context, refs, seenRefs, activeObjects);
180
+ return;
181
+ }
182
+ if (typeof value !== "object" || Array.isArray(value)) throw extractionError(context, path, "expected an input object");
183
+ if (activeObjects.has(value)) throw extractionError(context, path, "the input value contains a cycle");
184
+ activeObjects.add(value);
185
+ try {
186
+ const record = value;
187
+ for (const field of plan.body.fields) {
188
+ const fieldPath = `${path}.${field.name}`;
189
+ const result = readOwnField(record, field.name, context, fieldPath);
190
+ if ((!result.present || result.value === void 0) && field.hasDefault) continue;
191
+ extractValue(field.value, result.value, fieldPath, context, refs, seenRefs, activeObjects);
192
+ }
193
+ } finally {
194
+ activeObjects.delete(value);
195
+ }
196
+ }
197
+ var SchemaCompiledAttachmentExtractor = class {
198
+ context;
199
+ rootPlan;
200
+ constructor(context, rootPlan) {
201
+ this.context = context;
202
+ this.rootPlan = rootPlan;
203
+ }
204
+ extract(action) {
205
+ if (action.type !== this.context.actionType) throw extractionError(this.context, "input", "the action type does not match the compiled schema");
206
+ if (!this.rootPlan) return [];
207
+ if (action.input === null || typeof action.input !== "object" || Array.isArray(action.input)) throw extractionError(this.context, "input", "expected an input object");
208
+ const refs = [];
209
+ const seenRefs = /* @__PURE__ */ new Set();
210
+ const activeObjects = /* @__PURE__ */ new WeakSet();
211
+ activeObjects.add(action.input);
212
+ try {
213
+ const input = action.input;
214
+ for (const field of this.rootPlan.fields) {
215
+ const path = `input.${field.name}`;
216
+ const result = readOwnField(input, field.name, this.context, path);
217
+ if ((!result.present || result.value === void 0) && field.hasDefault) continue;
218
+ extractValue(field.value, result.value, path, this.context, refs, seenRefs, activeObjects);
219
+ }
220
+ } finally {
221
+ activeObjects.delete(action.input);
222
+ }
223
+ return refs;
224
+ }
225
+ };
226
+ function compileExtractor(module, actionType) {
227
+ const context = {
228
+ actionType,
229
+ documentType: module.documentModel.global.id,
230
+ version: module.version ?? 1
231
+ };
232
+ const specification = applicableSpecification(module, context);
233
+ const selected = selectOperation(parseOperations(specification, context), context);
234
+ if (selected === null || selected.operation.schema === null) return new SchemaCompiledAttachmentExtractor(context, null);
235
+ const effectiveSchema = buildEffectiveSchema(specification, context);
236
+ const operationName = selected.operation.name;
237
+ if (operationName === null) throw compilationError(context, "the operation has no name");
238
+ const rootName = `${pascalCase(operationName)}Input`;
239
+ const definitions = /* @__PURE__ */ new Map();
240
+ for (const type of Object.values(effectiveSchema.getTypeMap())) if (isInputObjectType(type) && !type.name.startsWith("__")) definitions.set(type.name, type);
241
+ if (!(selected.document?.definitions.filter((definition) => (definition.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION || definition.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION) && definition.name.value === rootName))?.length || !definitions.has(rootName)) throw compilationError(context, `the operation does not declare its expected root input "${rootName}"`);
242
+ return new SchemaCompiledAttachmentExtractor(context, compileRootPlan(rootName, definitions));
243
+ }
244
+ var AttachmentSchemaCompiler = class {
245
+ cache = /* @__PURE__ */ new WeakMap();
246
+ forModuleAction(module, actionType) {
247
+ let moduleCache = this.cache.get(module);
248
+ if (!moduleCache) {
249
+ moduleCache = /* @__PURE__ */ new Map();
250
+ this.cache.set(module, moduleCache);
251
+ }
252
+ const cached = moduleCache.get(actionType);
253
+ if (cached) return cached;
254
+ const compiled = compileExtractor(module, actionType);
255
+ moduleCache.set(actionType, compiled);
256
+ return compiled;
257
+ }
258
+ };
259
+ //#endregion
260
+ export { AttachmentSchemaCompiler as t };
261
+
262
+ //# sourceMappingURL=attachment-schema-compiler-rIaJpiHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-schema-compiler-rIaJpiHO.js","names":[],"sources":["../src/reference-index/attachment-schema-compiler.ts"],"sourcesContent":["import type { AttachmentRef } from \"@powerhousedao/reactor\";\nimport { generatorTypeDefs } from \"@powerhousedao/document-engineering/graphql\";\nimport type {\n Action,\n DocumentModelModule,\n DocumentSpecification,\n OperationSpecification,\n} from \"@powerhousedao/shared/document-model\";\nimport { constantCase, pascalCase } from \"change-case\";\nimport {\n buildASTSchema,\n getNamedType,\n isInputObjectType,\n isListType,\n isNonNullType,\n Kind,\n parse,\n print,\n type DocumentNode,\n type GraphQLInputObjectType,\n type GraphQLInputType,\n type GraphQLSchema,\n} from \"graphql\";\nimport { parseRef } from \"../ref.js\";\nimport type {\n CompiledAttachmentExtractor,\n IAttachmentSchemaCompiler,\n} from \"./types.js\";\n\nconst ATTACHMENT_REF_TYPE = \"AttachmentRef\";\nconst CODEGEN_SCALAR_NAMES = new Set([\n \"Unknown\",\n \"DateTime\",\n \"Address\",\n ATTACHMENT_REF_TYPE,\n ...Object.keys(generatorTypeDefs as Record<string, string>),\n]);\n\ntype CompilerContext = {\n actionType: string;\n documentType: string;\n version: number;\n};\n\ntype ParsedOperation = {\n document: DocumentNode | null;\n operation: OperationSpecification;\n};\n\ntype ObjectPlan = {\n fields: FieldPlan[];\n};\n\ntype FieldPlan = {\n hasDefault: boolean;\n name: string;\n value: ValuePlan;\n};\n\ntype ReadFieldResult =\n | { present: false; value: undefined }\n | { present: true; value: unknown };\n\ntype ValuePlan =\n | {\n kind: \"attachment\";\n required: boolean;\n }\n | {\n item: ValuePlan;\n kind: \"list\";\n required: boolean;\n }\n | {\n body: ObjectPlan;\n kind: \"object\";\n required: boolean;\n };\n\nfunction describeContext(context: CompilerContext): string {\n return `document type \"${context.documentType}\", version ${context.version}, action \"${context.actionType}\"`;\n}\n\nfunction compilationError(context: CompilerContext, reason: string): Error {\n return new Error(\n `Attachment schema compilation failed for ${describeContext(context)}: ${reason}`,\n );\n}\n\nfunction extractionError(\n context: CompilerContext,\n path: string,\n reason: string,\n): Error {\n return new Error(\n `Attachment extraction failed for ${describeContext(context)} at ${path}: ${reason}`,\n );\n}\n\nfunction applicableSpecification(\n module: DocumentModelModule,\n context: CompilerContext,\n): DocumentSpecification {\n const matches = module.documentModel.global.specifications.filter(\n (specification) => specification.version === context.version,\n );\n if (matches.length !== 1) {\n throw compilationError(\n context,\n matches.length === 0\n ? \"the module has no matching specification\"\n : \"the module has multiple matching specifications\",\n );\n }\n return matches[0];\n}\n\nfunction parseOperations(\n specification: DocumentSpecification,\n context: CompilerContext,\n): ParsedOperation[] {\n return specification.modules.flatMap((moduleSpecification) =>\n moduleSpecification.operations.map((operation) => {\n if (operation.schema === null) return { document: null, operation };\n try {\n return { document: parse(operation.schema), operation };\n } catch {\n throw compilationError(context, \"an operation has invalid GraphQL SDL\");\n }\n }),\n );\n}\n\nfunction selectOperation(\n operations: ParsedOperation[],\n context: CompilerContext,\n): ParsedOperation | null {\n const matches = operations.filter(\n ({ operation }) =>\n operation.name !== null &&\n constantCase(operation.name) === context.actionType,\n );\n if (matches.length > 1) {\n throw compilationError(context, \"multiple operations map to the action\");\n }\n // Base/system actions (document creation, renames, undo) are not part of a\n // model's specification, so they cannot declare AttachmentRef fields.\n // They compile to the no-reference fast path instead of failing the stream.\n if (matches.length === 0) return null;\n return matches[0];\n}\n\nfunction buildEffectiveSchema(\n specification: DocumentSpecification,\n context: CompilerContext,\n): GraphQLSchema {\n const scalarSchemas = Array.from(\n CODEGEN_SCALAR_NAMES,\n (name) => `scalar ${name}`,\n );\n const stateSchemas = Object.values(specification.state).map(\n (state) => state.schema,\n );\n const operationSchemas = specification.modules.flatMap(\n (moduleSpecification) =>\n moduleSpecification.operations.flatMap((operation) =>\n operation.schema === null ? [] : [operation.schema],\n ),\n );\n\n try {\n const document = parse(\n [...scalarSchemas, ...stateSchemas, ...operationSchemas]\n .filter(Boolean)\n .join(\"\\n\\n\"),\n );\n return buildASTSchema(dedupeTypeDefinitions(document));\n } catch {\n throw compilationError(context, \"the effective GraphQL schema is invalid\");\n }\n}\n\n// Collapse identical repeats of a type (state schema vs operation schemas).\n// Conflicting or scalar duplicates stay in so the build still rejects them.\nfunction dedupeTypeDefinitions(document: DocumentNode): DocumentNode {\n const seen = new Map<string, string>();\n const definitions = document.definitions.filter((definition) => {\n if (\n !(\"name\" in definition) ||\n definition.name?.value === undefined ||\n definition.kind === Kind.SCALAR_TYPE_DEFINITION\n ) {\n return true;\n }\n const name = definition.name.value;\n const printed = print(definition);\n const existing = seen.get(name);\n if (existing === undefined) {\n seen.set(name, printed);\n return true;\n }\n return existing !== printed;\n });\n return { ...document, definitions };\n}\n\nfunction attachmentReachableTypes(\n definitions: Map<string, GraphQLInputObjectType>,\n): Set<string> {\n const reachable = new Set<string>();\n let changed = true;\n\n while (changed) {\n changed = false;\n for (const [name, definition] of definitions) {\n if (reachable.has(name)) continue;\n const reachesAttachment = Object.values(definition.getFields()).some(\n (field) => {\n const typeName = getNamedType(field.type).name;\n return (\n typeName === ATTACHMENT_REF_TYPE ||\n (definitions.has(typeName) && reachable.has(typeName))\n );\n },\n );\n if (reachesAttachment) {\n reachable.add(name);\n changed = true;\n }\n }\n }\n\n return reachable;\n}\n\nfunction compileValuePlan(\n type: GraphQLInputType,\n objectPlans: Map<string, ObjectPlan>,\n): ValuePlan {\n if (isNonNullType(type)) {\n return { ...compileValuePlan(type.ofType, objectPlans), required: true };\n }\n if (isListType(type)) {\n return {\n item: compileValuePlan(type.ofType, objectPlans),\n kind: \"list\",\n required: false,\n };\n }\n\n const typeName = type.name;\n if (typeName === ATTACHMENT_REF_TYPE) {\n return { kind: \"attachment\", required: false };\n }\n const body = objectPlans.get(typeName);\n if (!body) {\n throw new Error(`Internal attachment schema plan error for ${typeName}`);\n }\n return { body, kind: \"object\", required: false };\n}\n\nfunction compileRootPlan(\n rootName: string,\n definitions: Map<string, GraphQLInputObjectType>,\n): ObjectPlan | null {\n const reachable = attachmentReachableTypes(definitions);\n if (!reachable.has(rootName)) return null;\n\n const objectPlans = new Map<string, ObjectPlan>();\n for (const name of reachable) objectPlans.set(name, { fields: [] });\n\n for (const name of reachable) {\n const definition = definitions.get(name);\n const body = objectPlans.get(name);\n if (!definition || !body) continue;\n for (const field of Object.values(definition.getFields())) {\n const typeName = getNamedType(field.type).name;\n if (typeName !== ATTACHMENT_REF_TYPE && !reachable.has(typeName)) {\n continue;\n }\n body.fields.push({\n hasDefault: field.defaultValue !== undefined,\n name: field.name,\n value: compileValuePlan(field.type, objectPlans),\n });\n }\n }\n\n return objectPlans.get(rootName) ?? null;\n}\n\nfunction readOwnField(\n value: Record<string, unknown>,\n fieldName: string,\n context: CompilerContext,\n path: string,\n): ReadFieldResult {\n try {\n if (!Object.prototype.hasOwnProperty.call(value, fieldName)) {\n return { present: false, value: undefined };\n }\n return { present: true, value: value[fieldName] };\n } catch {\n throw extractionError(context, path, \"the declared field cannot be read\");\n }\n}\n\nfunction extractValue(\n plan: ValuePlan,\n value: unknown,\n path: string,\n context: CompilerContext,\n refs: AttachmentRef[],\n seenRefs: Set<string>,\n activeObjects: WeakSet<object>,\n): void {\n if (value === null || value === undefined) {\n if (plan.required) {\n throw extractionError(\n context,\n path,\n \"a required value is missing or null\",\n );\n }\n return;\n }\n\n if (plan.kind === \"attachment\") {\n if (typeof value !== \"string\") {\n throw extractionError(context, path, \"expected an AttachmentRef string\");\n }\n try {\n parseRef(value as AttachmentRef);\n } catch {\n throw extractionError(context, path, \"the AttachmentRef is malformed\");\n }\n if (!seenRefs.has(value)) {\n seenRefs.add(value);\n refs.push(value as AttachmentRef);\n }\n return;\n }\n\n if (plan.kind === \"list\") {\n if (!Array.isArray(value)) {\n throw extractionError(context, path, \"expected a list\");\n }\n for (let index = 0; index < value.length; index += 1) {\n extractValue(\n plan.item,\n value[index],\n `${path}[${index}]`,\n context,\n refs,\n seenRefs,\n activeObjects,\n );\n }\n return;\n }\n\n if (typeof value !== \"object\" || Array.isArray(value)) {\n throw extractionError(context, path, \"expected an input object\");\n }\n if (activeObjects.has(value)) {\n throw extractionError(context, path, \"the input value contains a cycle\");\n }\n\n activeObjects.add(value);\n try {\n const record = value as Record<string, unknown>;\n for (const field of plan.body.fields) {\n const fieldPath = `${path}.${field.name}`;\n const result = readOwnField(record, field.name, context, fieldPath);\n if ((!result.present || result.value === undefined) && field.hasDefault) {\n continue;\n }\n extractValue(\n field.value,\n result.value,\n fieldPath,\n context,\n refs,\n seenRefs,\n activeObjects,\n );\n }\n } finally {\n activeObjects.delete(value);\n }\n}\n\nclass SchemaCompiledAttachmentExtractor implements CompiledAttachmentExtractor {\n constructor(\n private readonly context: CompilerContext,\n private readonly rootPlan: ObjectPlan | null,\n ) {}\n\n extract(action: Action): AttachmentRef[] {\n if (action.type !== this.context.actionType) {\n throw extractionError(\n this.context,\n \"input\",\n \"the action type does not match the compiled schema\",\n );\n }\n if (!this.rootPlan) return [];\n if (\n action.input === null ||\n typeof action.input !== \"object\" ||\n Array.isArray(action.input)\n ) {\n throw extractionError(this.context, \"input\", \"expected an input object\");\n }\n\n const refs: AttachmentRef[] = [];\n const seenRefs = new Set<string>();\n const activeObjects = new WeakSet<object>();\n activeObjects.add(action.input);\n try {\n const input = action.input as Record<string, unknown>;\n for (const field of this.rootPlan.fields) {\n const path = `input.${field.name}`;\n const result = readOwnField(input, field.name, this.context, path);\n if (\n (!result.present || result.value === undefined) &&\n field.hasDefault\n ) {\n continue;\n }\n extractValue(\n field.value,\n result.value,\n path,\n this.context,\n refs,\n seenRefs,\n activeObjects,\n );\n }\n } finally {\n activeObjects.delete(action.input);\n }\n return refs;\n }\n}\n\nfunction compileExtractor(\n module: DocumentModelModule,\n actionType: string,\n): CompiledAttachmentExtractor {\n const context: CompilerContext = {\n actionType,\n documentType: module.documentModel.global.id,\n version: module.version ?? 1,\n };\n const specification = applicableSpecification(module, context);\n const operations = parseOperations(specification, context);\n const selected = selectOperation(operations, context);\n if (selected === null || selected.operation.schema === null) {\n return new SchemaCompiledAttachmentExtractor(context, null);\n }\n const effectiveSchema = buildEffectiveSchema(specification, context);\n\n const operationName = selected.operation.name;\n if (operationName === null) {\n throw compilationError(context, \"the operation has no name\");\n }\n const rootName = `${pascalCase(operationName)}Input`;\n const definitions = new Map<string, GraphQLInputObjectType>();\n for (const type of Object.values(effectiveSchema.getTypeMap())) {\n if (isInputObjectType(type) && !type.name.startsWith(\"__\")) {\n definitions.set(type.name, type);\n }\n }\n const rootDefinitions = selected.document?.definitions.filter(\n (definition) =>\n (definition.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION ||\n definition.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION) &&\n definition.name.value === rootName,\n );\n if (!rootDefinitions?.length || !definitions.has(rootName)) {\n throw compilationError(\n context,\n `the operation does not declare its expected root input \"${rootName}\"`,\n );\n }\n\n return new SchemaCompiledAttachmentExtractor(\n context,\n compileRootPlan(rootName, definitions),\n );\n}\n\nexport class AttachmentSchemaCompiler implements IAttachmentSchemaCompiler {\n private readonly cache = new WeakMap<\n DocumentModelModule,\n Map<string, CompiledAttachmentExtractor>\n >();\n\n forModuleAction(\n module: DocumentModelModule,\n actionType: string,\n ): CompiledAttachmentExtractor {\n let moduleCache = this.cache.get(module);\n if (!moduleCache) {\n moduleCache = new Map();\n this.cache.set(module, moduleCache);\n }\n\n const cached = moduleCache.get(actionType);\n if (cached) return cached;\n\n const compiled = compileExtractor(module, actionType);\n moduleCache.set(actionType, compiled);\n return compiled;\n }\n}\n"],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { $ as AttachmentPending, A as IReservationStore, B as AttachmentStatus, C as IAttachmentReader, D as IAttachmentTransportFactory, E as IAttachmentTransport, F as AttachmentDownloadTargetOptions, G as HashFirstReserveAttachmentOptions, H as AttachmentTransportConfig, I as AttachmentHeader, J as TransportFetchResult, K as Reservation, L as AttachmentMetadata, N as AttachmentDownloadOptions, O as IAttachmentUpload, P as AttachmentDownloadTarget, Q as AttachmentNotFound, R as AttachmentResponse, T as IAttachmentStore, U as AttachmentUploadResult, V as AttachmentTargetHeaders, W as AttachmentUploadTarget, X as UploadFirstReserveAttachmentOptions, Y as TransportResponse, Z as AttachmentAlreadyExists, _ as createRef, a as RemoteAttachmentUpload, at as SizeMismatch, b as parseAttachmentDownloadTarget, c as XhrUploadTransportOptions, d as AttachmentUploadResponse, et as AttachmentTransferError, f as AttachmentUploadTransport, g as ParsedRef, h as SwitchboardTransportConfig, i as RemoteAttachmentUploadFactory, it as ReservationNotFound, k as IAttachmentUploadFactory, l as createXhrUploadTransport, m as SwitchboardAttachmentTransport, n as createRemoteAttachmentService, nt as HashMismatch, o as RemoteReservationStore, ot as UploadTooLarge, p as createFetchUploadTransport, q as ReserveAttachmentOptions, r as RemoteAttachmentStore, rt as InvalidAttachmentRef, s as SwitchboardClientConfig, t as NullAttachmentTransport, tt as AttachmentTransferStage, u as AttachmentUploadRequest, v as parseRef, w as IAttachmentService, x as parseAttachmentUploadTarget, y as AttachmentService, z as AttachmentSendOptions } from "./null-attachment-transport-CMrO_ZKA.js";
1
+ import { A as InvalidAttachmentRef, D as AttachmentTransferStage, E as AttachmentTransferError, M as SizeMismatch, N as UploadTooLarge, O as HashMismatch, S as AttachmentAlreadyExists, T as AttachmentPending, _ as createRef, a as RemoteAttachmentUpload, b as parseAttachmentDownloadTarget, c as XhrUploadTransportOptions, d as AttachmentUploadResponse, f as AttachmentUploadTransport, g as ParsedRef, h as SwitchboardTransportConfig, i as RemoteAttachmentUploadFactory, j as ReservationNotFound, l as createXhrUploadTransport, m as SwitchboardAttachmentTransport, n as createRemoteAttachmentService, o as RemoteReservationStore, p as createFetchUploadTransport, r as RemoteAttachmentStore, s as SwitchboardClientConfig, t as NullAttachmentTransport, u as AttachmentUploadRequest, v as parseRef, w as AttachmentNotFound, x as parseAttachmentUploadTarget, y as AttachmentService } from "./null-attachment-transport-dg7vi6F4.js";
2
+ import { A as UploadFirstReserveAttachmentOptions, C as AttachmentUploadResult, D as ReserveAttachmentOptions, E as Reservation, O as TransportFetchResult, S as AttachmentTransportConfig, T as HashFirstReserveAttachmentOptions, _ as AttachmentResponse, a as IAttachmentTransport, b as AttachmentStatus, c as IAttachmentUploadFactory, f as AttachmentDownloadOptions, g as AttachmentMetadata, h as AttachmentHeader, i as IAttachmentStore, k as TransportResponse, l as IReservationStore, m as AttachmentDownloadTargetOptions, n as IAttachmentReader, o as IAttachmentTransportFactory, p as AttachmentDownloadTarget, r as IAttachmentService, s as IAttachmentUpload, v as AttachmentSendOptions, w as AttachmentUploadTarget, x as AttachmentTargetHeaders, y as AttachmentStatOptions } from "./interfaces-jHW9JXv1.js";
2
3
  import { AttachmentHash, AttachmentRef } from "@powerhousedao/reactor";
3
-
4
4
  //#region src/concurrency.d.ts
5
5
  /**
6
6
  * Ordered result of one batch item. `index` always mirrors the input
@@ -17,7 +17,8 @@ type BatchItemResult<R> = {
17
17
  error: unknown;
18
18
  };
19
19
  type RunWithConcurrencyOptions<R = unknown> = {
20
- /** Maximum simultaneously running workers. Must be a positive integer. */concurrency: number;
20
+ /** Maximum simultaneously running workers. Must be a positive integer. */
21
+ concurrency: number;
21
22
  /**
22
23
  * Whole-batch cancellation: unstarted items are rejected with the signal's
23
24
  * reason without ever starting, while already-started items keep running —
@@ -37,7 +38,7 @@ type RunWithConcurrencyOptions<R = unknown> = {
37
38
  * executions. Bounding starts (not just transfers) is what keeps memory flat:
38
39
  * an item's preprocessing (hashing/buffering) only begins when a slot frees.
39
40
  */
40
- declare function runWithConcurrency<T, R>(items: readonly T[], worker: (item: T, index: number) => Promise<R>, options: RunWithConcurrencyOptions<R>): Promise<BatchItemResult<R>[]>;
41
+ export declare function runWithConcurrency<T, R>(items: readonly T[], worker: (item: T, index: number) => Promise<R>, options: RunWithConcurrencyOptions<R>): Promise<BatchItemResult<R>[]>;
41
42
  //#endregion
42
43
  //#region src/progress.d.ts
43
44
  /**
@@ -50,26 +51,32 @@ declare function runWithConcurrency<T, R>(items: readonly T[], worker: (item: T,
50
51
  */
51
52
  type AttachmentStage = "hashing" | "reserving" | "uploading" | "requesting-download-target" | "downloading" | "done" | "error";
52
53
  type AttachmentProgress = {
53
- stage: AttachmentStage; /** Bytes moved so far within `stage`. */
54
- loaded: number; /** Denominator for `stage`: file.size for uploads, header.sizeBytes for downloads. */
55
- total: number | undefined; /** True when the stage is running but bytes cannot (yet) be observed. */
56
- indeterminate: boolean; /** Only on a terminal `done` where dedup skipped the transfer entirely. */
54
+ stage: AttachmentStage;
55
+ /** Bytes moved so far within `stage`. */
56
+ loaded: number;
57
+ /** Denominator for `stage`: file.size for uploads, header.sizeBytes for downloads. */
58
+ total: number | undefined;
59
+ /** True when the stage is running but bytes cannot (yet) be observed. */
60
+ indeterminate: boolean;
61
+ /** Only on a terminal `done` where dedup skipped the transfer entirely. */
57
62
  deduped?: true;
58
63
  };
59
64
  type AttachmentProgressListener = (progress: AttachmentProgress) => void;
60
65
  type AttachmentProgressOptions = {
61
- onProgress?: AttachmentProgressListener; /** Min ms between byte events within a stage. Default 100. 0 emits every observation. */
66
+ onProgress?: AttachmentProgressListener;
67
+ /** Min ms between byte events within a stage. Default 100. 0 emits every observation. */
62
68
  throttleMs?: number;
63
69
  };
64
- declare const DEFAULT_PROGRESS_THROTTLE_MS = 100;
70
+ export declare const DEFAULT_PROGRESS_THROTTLE_MS = 100;
65
71
  /**
66
72
  * Fraction in 0..1 for a progress event. Indeterminate and unknown-total
67
73
  * events read as 0 — a bar cannot honestly show a position it does not know.
68
74
  * A zero total is complete by definition (the dedup case moves no bytes).
69
75
  */
70
- declare function progressFraction(progress: AttachmentProgress): number;
76
+ export declare function progressFraction(progress: AttachmentProgress): number;
71
77
  type ProgressEmitterOptions = AttachmentProgressOptions & {
72
- /** Injected clock so throttle tests stay synchronous. */now?: () => number;
78
+ /** Injected clock so throttle tests stay synchronous. */
79
+ now?: () => number;
73
80
  };
74
81
  /**
75
82
  * Emits `AttachmentProgress` for one single-item operation, upholding:
@@ -86,7 +93,7 @@ type ProgressEmitterOptions = AttachmentProgressOptions & {
86
93
  * ordering, and is unnecessary because `finish()` always emits
87
94
  * `loaded === total`, making a dropped last intra-stage tick invisible.
88
95
  */
89
- declare class ProgressEmitter {
96
+ export declare class ProgressEmitter {
90
97
  private readonly listener;
91
98
  private readonly throttleMs;
92
99
  private readonly now;
@@ -128,7 +135,9 @@ declare class ProgressEmitter {
128
135
  private emit;
129
136
  }
130
137
  type ByteProgressHooks = {
131
- /** Cumulative bytes handed to the consumer. */onBytes?: (loaded: number) => void; /** The source ended and every byte reached the consumer. */
138
+ /** Cumulative bytes handed to the consumer. */
139
+ onBytes?: (loaded: number) => void;
140
+ /** The source ended and every byte reached the consumer. */
132
141
  onDone?: () => void;
133
142
  onError?: (error: unknown) => void;
134
143
  };
@@ -150,10 +159,10 @@ type ByteProgressHooks = {
150
159
  * Returns `source` unchanged when no hook is supplied, so a caller with no
151
160
  * listener pays nothing.
152
161
  */
153
- declare function withByteProgress(source: ReadableStream<Uint8Array>, hooks: ByteProgressHooks): ReadableStream<Uint8Array>;
162
+ export declare function withByteProgress(source: ReadableStream<Uint8Array>, hooks: ByteProgressHooks): ReadableStream<Uint8Array>;
154
163
  //#endregion
155
164
  //#region src/client.d.ts
156
- type PreprocessResult = {
165
+ export type PreprocessResult = {
157
166
  ref: AttachmentRef;
158
167
  hash: AttachmentHash;
159
168
  sizeBytes: number;
@@ -161,10 +170,11 @@ type PreprocessResult = {
161
170
  data: ReadableStream<Uint8Array>;
162
171
  stream: () => ReadableStream<Uint8Array>;
163
172
  };
164
- type AttachmentUploadInput = {
173
+ export type AttachmentUploadInput = {
165
174
  file: Blob;
166
175
  fileName?: string;
167
- mimeType?: string; /** Per-item cancellation, checked between stages. */
176
+ mimeType?: string;
177
+ /** Per-item cancellation, checked between stages. */
168
178
  signal?: AbortSignal;
169
179
  };
170
180
  /**
@@ -175,7 +185,7 @@ type AttachmentUploadInput = {
175
185
  * upload. Passing the result back in skips the hashing stage rather than
176
186
  * faking a zero-millisecond one.
177
187
  */
178
- type AttachmentPreprocessedUploadInput = {
188
+ export type AttachmentPreprocessedUploadInput = {
179
189
  preprocessed: PreprocessResult;
180
190
  signal?: AbortSignal;
181
191
  };
@@ -183,7 +193,7 @@ type AttachmentPreprocessedUploadInput = {
183
193
  * Every remote download names the document that authorizes its ref; batches
184
194
  * may freely mix documents because the anchor travels with each item.
185
195
  */
186
- type AttachmentDownloadInput = {
196
+ export type AttachmentDownloadInput = {
187
197
  documentId: string;
188
198
  ref: AttachmentRef;
189
199
  signal?: AbortSignal;
@@ -194,25 +204,27 @@ type AttachmentDownloadInput = {
194
204
  * blob-producing conveniences let callers override what the server header
195
205
  * reports from upload time.
196
206
  */
197
- type AttachmentBlobOptions = {
207
+ export type AttachmentBlobOptions = {
198
208
  mimeType?: string;
199
209
  };
200
- type AttachmentSaveOptions = {
210
+ export type AttachmentSaveOptions = {
201
211
  fileName?: string;
202
212
  mimeType?: string;
203
213
  };
204
- type AttachmentBlobResult = {
214
+ export type AttachmentBlobResult = {
205
215
  blob: Blob;
206
216
  header: AttachmentHeader;
207
217
  };
208
- type AttachmentObjectUrl = {
209
- /** Ready for img/iframe/video src. Pins memory until revoke() is called. */url: string;
218
+ export type AttachmentObjectUrl = {
219
+ /** Ready for img/iframe/video src. Pins memory until revoke() is called. */
220
+ url: string;
210
221
  header: AttachmentHeader;
211
222
  revoke: () => void;
212
223
  };
213
- type AttachmentShareLinkInput = {
224
+ export type AttachmentShareLinkInput = {
214
225
  documentId: string;
215
- ref: AttachmentRef; /** Requested link lifetime in seconds; the server clamps to its maximum. */
226
+ ref: AttachmentRef;
227
+ /** Requested link lifetime in seconds; the server clamps to its maximum. */
216
228
  expiresIn?: number;
217
229
  signal?: AbortSignal;
218
230
  };
@@ -221,7 +233,7 @@ type AttachmentShareLinkInput = {
221
233
  * expiresAtUtc, with no login and no document access. Minting one requires
222
234
  * document read access; once minted it cannot be revoked before expiry.
223
235
  */
224
- type AttachmentShareLink = {
236
+ export type AttachmentShareLink = {
225
237
  url: string;
226
238
  expiresAtUtc: string;
227
239
  };
@@ -231,8 +243,10 @@ type AttachmentShareLink = {
231
243
  * a presentation decision the client cannot make, and a confirmed dedup would
232
244
  * shrink the denominator mid-flight.
233
245
  */
234
- type AttachmentBatchOptions = {
235
- /** Bounds preprocessing and transfer together. Defaults to 4. */concurrency?: number; /** Whole-batch cancellation: stops unstarted items. */
246
+ export type AttachmentBatchOptions = {
247
+ /** Bounds preprocessing and transfer together. Defaults to 4. */
248
+ concurrency?: number;
249
+ /** Whole-batch cancellation: stops unstarted items. */
236
250
  signal?: AbortSignal;
237
251
  onProgress?: (progress: AttachmentProgress & {
238
252
  index: number;
@@ -241,17 +255,18 @@ type AttachmentBatchOptions = {
241
255
  * Fired as each item settles, including items the signal skipped before they
242
256
  * started, so `settled` always reaches `total`.
243
257
  */
244
- onItemSettled?: (counts: AttachmentBatchCounts) => void; /** Min ms between byte events, applied per item rather than batch-wide. */
258
+ onItemSettled?: (counts: AttachmentBatchCounts) => void;
259
+ /** Min ms between byte events, applied per item rather than batch-wide. */
245
260
  throttleMs?: number;
246
261
  };
247
- type AttachmentBatchCounts = {
262
+ export type AttachmentBatchCounts = {
248
263
  settled: number;
249
264
  completed: number;
250
265
  failed: number;
251
266
  total: number;
252
267
  };
253
- declare const DEFAULT_ATTACHMENT_BATCH_CONCURRENCY = 4;
254
- interface IAttachmentClient {
268
+ export declare const DEFAULT_ATTACHMENT_BATCH_CONCURRENCY = 4;
269
+ export interface IAttachmentClient {
255
270
  preprocess(file: Blob, opts?: {
256
271
  fileName?: string;
257
272
  mimeType?: string;
@@ -303,7 +318,8 @@ interface IAttachmentClient {
303
318
  uploadMany(inputs: readonly AttachmentUploadInput[], options?: AttachmentBatchOptions): Promise<BatchItemResult<AttachmentUploadResult>[]>;
304
319
  downloadMany(inputs: readonly AttachmentDownloadInput[], options?: AttachmentBatchOptions): Promise<BatchItemResult<AttachmentResponse>[]>;
305
320
  }
306
- declare function createAttachmentClient(service: IAttachmentService): IAttachmentClient;
321
+ export declare function createAttachmentClient(service: IAttachmentService): IAttachmentClient;
307
322
  //#endregion
308
- export { AttachmentAlreadyExists, AttachmentBatchCounts, AttachmentBatchOptions, AttachmentBlobOptions, AttachmentBlobResult, AttachmentDownloadInput, type AttachmentDownloadOptions, type AttachmentDownloadTarget, type AttachmentDownloadTargetOptions, type AttachmentHeader, type AttachmentMetadata, AttachmentNotFound, AttachmentObjectUrl, AttachmentPending, AttachmentPreprocessedUploadInput, type AttachmentProgress, type AttachmentProgressListener, type AttachmentProgressOptions, type AttachmentResponse, AttachmentSaveOptions, type AttachmentSendOptions, AttachmentService, AttachmentShareLink, AttachmentShareLinkInput, type AttachmentStage, type AttachmentStatus, type AttachmentTargetHeaders, AttachmentTransferError, type AttachmentTransferStage, type AttachmentTransportConfig, AttachmentUploadInput, type AttachmentUploadRequest, type AttachmentUploadResponse, type AttachmentUploadResult, type AttachmentUploadTarget, type AttachmentUploadTransport, type BatchItemResult, type ByteProgressHooks, DEFAULT_ATTACHMENT_BATCH_CONCURRENCY, DEFAULT_PROGRESS_THROTTLE_MS, type HashFirstReserveAttachmentOptions, HashMismatch, IAttachmentClient, type IAttachmentReader, type IAttachmentService, type IAttachmentStore, type IAttachmentTransport, type IAttachmentTransportFactory, type IAttachmentUpload, type IAttachmentUploadFactory, type IReservationStore, InvalidAttachmentRef, NullAttachmentTransport, type ParsedRef, PreprocessResult, ProgressEmitter, type ProgressEmitterOptions, RemoteAttachmentStore, RemoteAttachmentUpload, RemoteAttachmentUploadFactory, RemoteReservationStore, type Reservation, ReservationNotFound, type ReserveAttachmentOptions, type RunWithConcurrencyOptions, SizeMismatch, SwitchboardAttachmentTransport, type SwitchboardClientConfig, type SwitchboardTransportConfig, type TransportFetchResult, type TransportResponse, type UploadFirstReserveAttachmentOptions, UploadTooLarge, type XhrUploadTransportOptions, createAttachmentClient, createFetchUploadTransport, createRef, createRemoteAttachmentService, createXhrUploadTransport, parseAttachmentDownloadTarget, parseAttachmentUploadTarget, parseRef, progressFraction, runWithConcurrency, withByteProgress };
323
+ export { AttachmentAlreadyExists, type AttachmentDownloadOptions, type AttachmentDownloadTarget, type AttachmentDownloadTargetOptions, type AttachmentHeader, type AttachmentMetadata, AttachmentNotFound, AttachmentPending, type AttachmentProgress, type AttachmentProgressListener, type AttachmentProgressOptions, type AttachmentResponse, type AttachmentSendOptions, AttachmentService, type AttachmentStage, type AttachmentStatOptions, type AttachmentStatus, type AttachmentTargetHeaders, AttachmentTransferError, type AttachmentTransferStage, type AttachmentTransportConfig, type AttachmentUploadRequest, type AttachmentUploadResponse, type AttachmentUploadResult, type AttachmentUploadTarget, type AttachmentUploadTransport, type BatchItemResult, type ByteProgressHooks, type HashFirstReserveAttachmentOptions, HashMismatch, type IAttachmentReader, type IAttachmentService, type IAttachmentStore, type IAttachmentTransport, type IAttachmentTransportFactory, type IAttachmentUpload, type IAttachmentUploadFactory, type IReservationStore, InvalidAttachmentRef, NullAttachmentTransport, type ParsedRef, type ProgressEmitterOptions, RemoteAttachmentStore, RemoteAttachmentUpload, RemoteAttachmentUploadFactory, RemoteReservationStore, type Reservation, ReservationNotFound, type ReserveAttachmentOptions, type RunWithConcurrencyOptions, SizeMismatch, SwitchboardAttachmentTransport, type SwitchboardClientConfig, type SwitchboardTransportConfig, type TransportFetchResult, type TransportResponse, type UploadFirstReserveAttachmentOptions, UploadTooLarge, type XhrUploadTransportOptions, createFetchUploadTransport, createRef, createRemoteAttachmentService, createXhrUploadTransport, parseAttachmentDownloadTarget, parseAttachmentUploadTarget, parseRef };
324
+ export {};
309
325
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","names":[],"sources":["../src/concurrency.ts","../src/progress.ts","../src/client.ts"],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","names":[],"sources":["../src/concurrency.ts","../src/progress.ts","../src/client.ts"],"mappings":";;;;;;;;;KAKY,gBAAgB;EACtB;EAAe;EAAqB,OAAO;;EAC3C;EAAe;EAAoB;;KAE7B,0BAA0B;;EAEpC;;;;;;EAMA,SAAS;;;;;;;EAOT,aAAa,QAAQ,gBAAgB;;;;;;;wBAQjB,mBAAmB,GAAG,GAC1C,gBAAgB,KAChB,SAAS,MAAM,GAAG,kBAAkB,QAAQ,IAC5C,SAAS,0BAA0B,KAClC,QAAQ,gBAAgB;;;;;;;;;;;KC3Bf;KASA;EACV,OAAO;;EAEP;;EAEA;;EAEA;;EAEA;;KAGU,8BAA8B,UAAU;KAExC;EACV,aAAa;;EAEb;;qBAGW;;;;;;wBAOG,iBAAiB,UAAU;KAS/B,yBAAyB;;EAEnC;;;;;;;;;;;;;;;;;qBAkBW;mBACM;mBACA;mBACA;UAET;UACA;UACA;UACA;UACA;UACA;EAER,YAAY,UAAU;;MAOlB;;;;;;EASJ,MAAM,OAAO,iBAAiB;IAAY;;;;;;EAkB1C,MAAM,gBAAgB;;;;;EAoBtB,OAAO;IAAa;IAAiB;IAAgB;;;EAerD;;EAKA;UAWQ;;KAME;;EAEV,WAAW;;EAEX;EACA,WAAW;;;;;;;;;;;;;;;;;;;;wBAqBG,iBACd,QAAQ,eAAe,aACvB,OAAO,oBACN,eAAe;;;YCjGN;EACV,KAAK;EACL,MAAM;EACN;EACA,SAAS;EACT,MAAM,eAAe;EACrB,cAAc,eAAe;;YAGnB;EACV,MAAM;EACN;EACA;;EAEA,SAAS;;;;;;;;;;YAWC;EACV,cAAc;EACd,SAAS;;;;;;YAOC;EACV;EACA,KAAK;EACL,SAAS;;;;;;;;YASC;EACV;;YAGU;EACV;EACA;;YAGU;EACV,MAAM;EACN,QAAQ;;YAGE;;EAEV;EACA,QAAQ;EACR;;YAGU;EACV;EACA,KAAK;;EAEL;EACA,SAAS;;;;;;;YAQC;EACV;EACA;;;;;;;;YASU;;EAEV;;EAEA,SAAS;EACT,cAAc,UAAU;IAAuB;;;;;;EAK/C,iBAAiB,QAAQ;;EAEzB;;YAGU;EACV;EACA;EACA;EACA;;qBAGW;iBAEI;EACf,WACE,MAAM,MACN;IAAS;IAAmB;MAC3B,QAAQ;EACX,QACE,SAAS,mCACT,OAAO,QAAQ,sBAAsB,QAAQ,0BAC5C,QAAQ;;;;;;;;EAQX,OACE,OAAO,wBAAwB,mCAC/B,UAAU,4BACT,QAAQ;;;;;;;;;EASX,SACE,OAAO,yBACP,UAAU,4BACT,QAAQ;;;;;;EAMX,aACE,OAAO,yBACP,UAAU,wBAAwB,4BACjC,QAAQ;;;;;;EAMX,eACE,OAAO,yBACP,UAAU,wBAAwB,4BACjC;;;;;;EAMH,kBACE,OAAO,yBACP,UAAU,wBAAwB,4BACjC,QAAQ;;;;;;;;EAQX,aAAa,OAAO,2BAA2B,QAAQ;EACvD,WACE,iBAAiB,yBACjB,UAAU,yBACT,QAAQ,gBAAgB;EAC3B,aACE,iBAAiB,2BACjB,UAAU,yBACT,QAAQ,gBAAgB;;wBA6Xb,uBACd,SAAS,qBACR"}
package/dist/client.js CHANGED
@@ -1,4 +1,6 @@
1
- import { C as UploadTooLarge, S as SizeMismatch, _ as AttachmentPending, a as RemoteAttachmentUpload, b as InvalidAttachmentRef, c as createFetchUploadTransport, d as createRef, f as parseRef, g as AttachmentNotFound, h as AttachmentAlreadyExists, i as RemoteAttachmentUploadFactory, l as SwitchboardAttachmentTransport, m as parseAttachmentUploadTarget, n as createRemoteAttachmentService, o as RemoteReservationStore, p as parseAttachmentDownloadTarget, r as RemoteAttachmentStore, s as createXhrUploadTransport, t as NullAttachmentTransport, u as AttachmentService, v as AttachmentTransferError, x as ReservationNotFound, y as HashMismatch } from "./null-attachment-transport-CrsUafCi.js";
1
+ import { a as parseRef, c as AttachmentPending, f as InvalidAttachmentRef, h as UploadTooLarge, i as createRef, l as AttachmentTransferError, m as SizeMismatch, o as AttachmentAlreadyExists, p as ReservationNotFound, s as AttachmentNotFound, t as SwitchboardAttachmentTransport, u as HashMismatch } from "./switchboard-attachment-transport-BH3ZAmxE.js";
2
+ import { a as RemoteAttachmentUpload, c as createFetchUploadTransport, d as parseAttachmentUploadTarget, i as RemoteAttachmentUploadFactory, l as AttachmentService, n as createRemoteAttachmentService, o as RemoteReservationStore, r as RemoteAttachmentStore, s as createXhrUploadTransport, t as NullAttachmentTransport, u as parseAttachmentDownloadTarget } from "./null-attachment-transport-BGG9cRC-.js";
3
+ import { t as sha256Hex } from "./hash-CKHeI4AH.js";
2
4
  //#region src/concurrency.ts
3
5
  /**
4
6
  * Runs `worker` over `items` with a hard upper bound on simultaneous
@@ -24,10 +26,11 @@ async function runWithConcurrency(items, worker, options) {
24
26
  continue;
25
27
  }
26
28
  try {
29
+ const value = await worker(items[index], index);
27
30
  results[index] = {
28
31
  index,
29
32
  status: "fulfilled",
30
- value: await worker(items[index], index)
33
+ value
31
34
  };
32
35
  } catch (error) {
33
36
  results[index] = {
@@ -238,6 +241,21 @@ function isAttachmentAlreadyExists(err) {
238
241
  if (err instanceof AttachmentAlreadyExists) return true;
239
242
  return err instanceof Error && err.name === "AttachmentAlreadyExists" && typeof err.hash === "string" && typeof err.ref === "string";
240
243
  }
244
+ function dedupedHeader(hash, options) {
245
+ const now = (/* @__PURE__ */ new Date()).toISOString();
246
+ return {
247
+ hash,
248
+ mimeType: options.mimeType,
249
+ fileName: options.fileName,
250
+ sizeBytes: options.sizeBytes,
251
+ extension: options.extension ?? null,
252
+ status: "available",
253
+ source: "local",
254
+ createdAtUtc: now,
255
+ lastAccessedAtUtc: now,
256
+ expiresAtUtc: null
257
+ };
258
+ }
241
259
  function streamFromBuffer(buf) {
242
260
  return new ReadableStream({ start(controller) {
243
261
  controller.enqueue(buf);
@@ -277,14 +295,14 @@ function batchRunOptions(total, options) {
277
295
  };
278
296
  }
279
297
  var AttachmentClientImpl = class {
298
+ service;
280
299
  constructor(service) {
281
300
  this.service = service;
282
301
  }
283
302
  async preprocess(file, opts) {
284
303
  const buf = await file.arrayBuffer();
285
304
  const bytes = new Uint8Array(buf);
286
- const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
287
- const hash = Array.from(new Uint8Array(digest)).map((b) => b.toString(16).padStart(2, "0")).join("");
305
+ const hash = await sha256Hex(bytes);
288
306
  const ref = createRef(hash);
289
307
  const sizeBytes = file.size;
290
308
  const options = {
@@ -317,13 +335,12 @@ var AttachmentClientImpl = class {
317
335
  };
318
336
  } catch (err) {
319
337
  if (!isAttachmentAlreadyExists(err)) throw err;
320
- const header = await this.service.stat(err.ref);
321
338
  return {
322
339
  kind: "deduped",
323
340
  result: {
324
341
  hash: err.hash,
325
342
  ref: err.ref,
326
- header
343
+ header: dedupedHeader(err.hash, options)
327
344
  }
328
345
  };
329
346
  }