@contember/react-client 2.0.0-alpha.4 → 2.0.0-alpha.6

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.
Files changed (74) hide show
  1. package/dist/development/index.cjs +0 -2
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +0 -2
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/production/index.cjs +0 -2
  6. package/dist/production/index.cjs.map +1 -1
  7. package/dist/production/index.js +0 -2
  8. package/dist/production/index.js.map +1 -1
  9. package/dist/types/index.d.ts +0 -1
  10. package/dist/types/index.d.ts.map +1 -1
  11. package/dist/types/tsconfig.tsbuildinfo +1 -1
  12. package/package.json +3 -4
  13. package/src/index.ts +0 -1
  14. package/src/tsconfig.json +1 -2
  15. package/dist/development/upload/fileUploadReducer.cjs +0 -149
  16. package/dist/development/upload/fileUploadReducer.cjs.map +0 -1
  17. package/dist/development/upload/fileUploadReducer.js +0 -149
  18. package/dist/development/upload/fileUploadReducer.js.map +0 -1
  19. package/dist/development/upload/toFileId.cjs +0 -10
  20. package/dist/development/upload/toFileId.cjs.map +0 -1
  21. package/dist/development/upload/toFileId.js +0 -10
  22. package/dist/development/upload/toFileId.js.map +0 -1
  23. package/dist/development/upload/useFileUpload.cjs +0 -166
  24. package/dist/development/upload/useFileUpload.cjs.map +0 -1
  25. package/dist/development/upload/useFileUpload.js +0 -166
  26. package/dist/development/upload/useFileUpload.js.map +0 -1
  27. package/dist/production/upload/fileUploadReducer.cjs +0 -149
  28. package/dist/production/upload/fileUploadReducer.cjs.map +0 -1
  29. package/dist/production/upload/fileUploadReducer.js +0 -149
  30. package/dist/production/upload/fileUploadReducer.js.map +0 -1
  31. package/dist/production/upload/toFileId.cjs +0 -10
  32. package/dist/production/upload/toFileId.cjs.map +0 -1
  33. package/dist/production/upload/toFileId.js +0 -10
  34. package/dist/production/upload/toFileId.js.map +0 -1
  35. package/dist/production/upload/useFileUpload.cjs +0 -166
  36. package/dist/production/upload/useFileUpload.cjs.map +0 -1
  37. package/dist/production/upload/useFileUpload.js +0 -166
  38. package/dist/production/upload/useFileUpload.js.map +0 -1
  39. package/dist/types/upload/FileId.d.ts +0 -2
  40. package/dist/types/upload/FileId.d.ts.map +0 -1
  41. package/dist/types/upload/FileUploadAction.d.ts +0 -24
  42. package/dist/types/upload/FileUploadAction.d.ts.map +0 -1
  43. package/dist/types/upload/FileUploadCompoundState.d.ts +0 -4
  44. package/dist/types/upload/FileUploadCompoundState.d.ts.map +0 -1
  45. package/dist/types/upload/FileUploadMetadata.d.ts +0 -6
  46. package/dist/types/upload/FileUploadMetadata.d.ts.map +0 -1
  47. package/dist/types/upload/FileUploadMultiTemporalState.d.ts +0 -7
  48. package/dist/types/upload/FileUploadMultiTemporalState.d.ts.map +0 -1
  49. package/dist/types/upload/FileUploadOperations.d.ts +0 -18
  50. package/dist/types/upload/FileUploadOperations.d.ts.map +0 -1
  51. package/dist/types/upload/FileWithMetadata.d.ts +0 -8
  52. package/dist/types/upload/FileWithMetadata.d.ts.map +0 -1
  53. package/dist/types/upload/SingleFileUploadState.d.ts +0 -35
  54. package/dist/types/upload/SingleFileUploadState.d.ts.map +0 -1
  55. package/dist/types/upload/fileUploadReducer.d.ts +0 -5
  56. package/dist/types/upload/fileUploadReducer.d.ts.map +0 -1
  57. package/dist/types/upload/index.d.ts +0 -8
  58. package/dist/types/upload/index.d.ts.map +0 -1
  59. package/dist/types/upload/toFileId.d.ts +0 -4
  60. package/dist/types/upload/toFileId.d.ts.map +0 -1
  61. package/dist/types/upload/useFileUpload.d.ts +0 -10
  62. package/dist/types/upload/useFileUpload.d.ts.map +0 -1
  63. package/src/upload/FileId.ts +0 -1
  64. package/src/upload/FileUploadAction.ts +0 -30
  65. package/src/upload/FileUploadCompoundState.ts +0 -7
  66. package/src/upload/FileUploadMetadata.ts +0 -6
  67. package/src/upload/FileUploadMultiTemporalState.ts +0 -7
  68. package/src/upload/FileUploadOperations.ts +0 -22
  69. package/src/upload/FileWithMetadata.ts +0 -8
  70. package/src/upload/SingleFileUploadState.ts +0 -43
  71. package/src/upload/fileUploadReducer.ts +0 -166
  72. package/src/upload/index.ts +0 -15
  73. package/src/upload/toFileId.ts +0 -12
  74. package/src/upload/useFileUpload.ts +0 -218
@@ -1,149 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const client = require("@contember/client");
4
- const utilities = require("@contember/utilities");
5
- const toFileId = require("./toFileId.cjs");
6
- const initializeFileUploadState = () => ({
7
- fileIdByFile: /* @__PURE__ */ new WeakMap(),
8
- state: /* @__PURE__ */ new Map()
9
- });
10
- const fileUploadReducer = (previousState, action) => {
11
- let newState = void 0;
12
- switch (action.type) {
13
- case "initialize": {
14
- for (const [fileId, metadata] of action.files) {
15
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
16
- readyState: "initializing",
17
- abortController: metadata.abortController,
18
- previewUrl: metadata.previewUrl,
19
- file: metadata.file
20
- });
21
- previousState.fileIdByFile.set(metadata.file, fileId);
22
- }
23
- break;
24
- }
25
- case "startUploading": {
26
- for (const [fileOrId, metadata] of action.files) {
27
- const fileId = toFileId.toFileId(previousState, fileOrId);
28
- const fileState = (newState ?? previousState.state).get(fileId);
29
- if (fileState === void 0 || fileState.readyState !== "initializing") {
30
- continue;
31
- }
32
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
33
- readyState: "uploading",
34
- abortController: fileState.abortController,
35
- file: fileState.file,
36
- metadata: metadata.metadata,
37
- // If the user didn't supply the metadata, then that's on them.
38
- previewUrl: fileState.previewUrl,
39
- progress: void 0,
40
- uploader: metadata.uploader
41
- });
42
- }
43
- break;
44
- }
45
- case "finishSuccessfully": {
46
- for (const [fileOrId, result] of action.result) {
47
- const fileId = toFileId.toFileId(previousState, fileOrId);
48
- const previousFileState = (newState ?? previousState.state).get(fileId);
49
- if (previousFileState === void 0 || previousFileState.readyState !== "uploading") {
50
- continue;
51
- }
52
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
53
- readyState: "success",
54
- file: previousFileState.file,
55
- metadata: previousFileState.metadata,
56
- previewUrl: previousFileState.previewUrl,
57
- result,
58
- uploader: previousFileState.uploader
59
- });
60
- }
61
- break;
62
- }
63
- case "finishWithError": {
64
- for (const errorSpec of action.error) {
65
- let fileOrId;
66
- let rawError;
67
- if (Array.isArray(errorSpec)) {
68
- [fileOrId, rawError] = errorSpec;
69
- } else {
70
- fileOrId = errorSpec;
71
- rawError = void 0;
72
- }
73
- const errors = [];
74
- if (rawError instanceof client.FileUploadError) {
75
- errors.push(rawError);
76
- } else if (Array.isArray(rawError)) {
77
- for (const error of rawError) {
78
- if (error instanceof client.FileUploadError) {
79
- errors.push(error);
80
- }
81
- }
82
- }
83
- const fileId = toFileId.toFileId(previousState, fileOrId);
84
- const previousFileState = (newState ?? previousState.state).get(fileId);
85
- if (previousFileState === void 0 || previousFileState.readyState !== "initializing" && previousFileState.readyState !== "uploading") {
86
- continue;
87
- }
88
- const uploader = previousFileState.readyState === "uploading" ? previousFileState.uploader : void 0;
89
- const metadata = previousFileState.readyState === "uploading" ? previousFileState.metadata : void 0;
90
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
91
- readyState: "error",
92
- errors: errors.length ? errors : void 0,
93
- rawError,
94
- file: previousFileState.file,
95
- metadata,
96
- previewUrl: previousFileState.previewUrl,
97
- uploader
98
- });
99
- }
100
- break;
101
- }
102
- case "purge": {
103
- for (const fileOrId of action.files) {
104
- const fileId = toFileId.toFileId(previousState, fileOrId);
105
- const fileState = (newState ?? previousState.state).get(fileId);
106
- if (fileState === void 0) {
107
- continue;
108
- }
109
- URL.revokeObjectURL(fileState.previewUrl);
110
- if (fileState.readyState === "initializing" || fileState.readyState === "uploading") {
111
- fileState.abortController.abort();
112
- }
113
- (newState ?? (newState = new Map(previousState.state))).delete(fileId);
114
- }
115
- break;
116
- }
117
- case "updateUploadProgress": {
118
- for (const [fileOrId, { progress }] of action.progress) {
119
- const fileId = toFileId.toFileId(previousState, fileOrId);
120
- const previousFileState = (newState ?? previousState.state).get(fileId);
121
- if (progress === void 0 || previousFileState === void 0 || previousFileState.readyState !== "uploading") {
122
- continue;
123
- }
124
- if (previousFileState.progress && Math.abs(progress - previousFileState.progress) < 0.01) {
125
- continue;
126
- }
127
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
128
- readyState: "uploading",
129
- file: previousFileState.file,
130
- uploader: previousFileState.uploader,
131
- abortController: previousFileState.abortController,
132
- previewUrl: previousFileState.previewUrl,
133
- metadata: previousFileState.metadata,
134
- progress
135
- });
136
- }
137
- break;
138
- }
139
- default:
140
- utilities.assertNever(action);
141
- }
142
- if (newState === void 0) {
143
- return previousState;
144
- }
145
- return { ...previousState, state: newState };
146
- };
147
- exports.fileUploadReducer = fileUploadReducer;
148
- exports.initializeFileUploadState = initializeFileUploadState;
149
- //# sourceMappingURL=fileUploadReducer.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fileUploadReducer.cjs","sources":["../../../src/upload/fileUploadReducer.ts"],"sourcesContent":["import { FileUploadError } from '@contember/client'\nimport { assertNever } from '@contember/utilities'\nimport type { FileId } from './FileId'\nimport type { FileUploadAction } from './FileUploadAction'\nimport type { FileUploadMultiTemporalState } from './FileUploadMultiTemporalState'\nimport { toFileId } from './toFileId'\n\nexport const initializeFileUploadState = <Result = unknown, Metadata = undefined>(): FileUploadMultiTemporalState<Result, Metadata> => ({\n\tfileIdByFile: new WeakMap<File, FileId>(),\n\tstate: new Map(),\n})\n\nexport const fileUploadReducer = <Result = unknown, Metadata = undefined>(\n\tpreviousState: FileUploadMultiTemporalState<Result, Metadata>,\n\taction: FileUploadAction<Result, Metadata>,\n): FileUploadMultiTemporalState<Result, Metadata> => {\n\tlet newState: undefined | FileUploadMultiTemporalState<Result, Metadata>['state'] = undefined\n\n\tswitch (action.type) {\n\t\tcase 'initialize': {\n\t\t\tfor (const [fileId, metadata] of action.files) {\n\t\t\t\t// Deliberately allowing starting a new upload with the same id\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'initializing',\n\t\t\t\t\tabortController: metadata.abortController,\n\t\t\t\t\tpreviewUrl: metadata.previewUrl,\n\t\t\t\t\tfile: metadata.file,\n\t\t\t\t})\n\t\t\t\t// Deliberately mutating\n\t\t\t\tpreviousState.fileIdByFile.set(metadata.file, fileId)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'startUploading': {\n\t\t\tfor (const [fileOrId, metadata] of action.files) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst fileState = (newState ?? previousState.state).get(fileId)\n\n\t\t\t\tif (fileState === undefined || fileState.readyState !== 'initializing') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'uploading',\n\t\t\t\t\tabortController: fileState.abortController,\n\t\t\t\t\tfile: fileState.file,\n\t\t\t\t\tmetadata: metadata.metadata!, // If the user didn't supply the metadata, then that's on them.\n\t\t\t\t\tpreviewUrl: fileState.previewUrl,\n\t\t\t\t\tprogress: undefined,\n\t\t\t\t\tuploader: metadata.uploader,\n\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'finishSuccessfully': {\n\t\t\tfor (const [fileOrId, result] of action.result) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst previousFileState = (newState ?? previousState.state).get(fileId)\n\t\t\t\tif (previousFileState === undefined || previousFileState.readyState !== 'uploading') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'success',\n\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\tmetadata: previousFileState.metadata,\n\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\tresult,\n\t\t\t\t\tuploader: previousFileState.uploader,\n\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'finishWithError': {\n\t\t\tfor (const errorSpec of action.error) {\n\t\t\t\tlet fileOrId: File | FileId\n\t\t\t\tlet rawError: unknown\n\n\t\t\t\tif (Array.isArray(errorSpec)) {\n\t\t\t\t\t[fileOrId, rawError] = errorSpec\n\t\t\t\t} else {\n\t\t\t\t\tfileOrId = errorSpec\n\t\t\t\t\trawError = undefined\n\t\t\t\t}\n\n\t\t\t\tconst errors: FileUploadError[] = []\n\n\t\t\t\tif (rawError instanceof FileUploadError) {\n\t\t\t\t\terrors.push(rawError)\n\t\t\t\t} else if (Array.isArray(rawError)) {\n\t\t\t\t\tfor (const error of rawError) {\n\t\t\t\t\t\tif (error instanceof FileUploadError) {\n\t\t\t\t\t\t\terrors.push(error)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst previousFileState = (newState ?? previousState.state).get(fileId)\n\t\t\t\tif (\n\t\t\t\t\tpreviousFileState === undefined ||\n\t\t\t\t\t(previousFileState.readyState !== 'initializing' && previousFileState.readyState !== 'uploading')\n\t\t\t\t) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst uploader = previousFileState.readyState === 'uploading' ? previousFileState.uploader : undefined\n\t\t\t\tconst metadata = previousFileState.readyState === 'uploading' ? previousFileState.metadata : undefined\n\t\t\t\t\t; (newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\t\treadyState: 'error',\n\t\t\t\t\t\terrors: errors.length ? errors : undefined,\n\t\t\t\t\t\trawError,\n\t\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\t\tuploader,\n\t\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'purge': {\n\t\t\tfor (const fileOrId of action.files) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst fileState = (newState ?? previousState.state).get(fileId)\n\n\t\t\t\tif (fileState === undefined) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tURL.revokeObjectURL(fileState.previewUrl)\n\t\t\t\tif (fileState.readyState === 'initializing' || fileState.readyState === 'uploading') {\n\t\t\t\t\tfileState.abortController.abort() // This is a bit naughty… We shouldn't do this from here.\n\t\t\t\t}\n\t\t\t\t(newState ??= new Map(previousState.state)).delete(fileId)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'updateUploadProgress': {\n\t\t\tfor (const [fileOrId, { progress }] of action.progress) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst previousFileState = (newState ?? previousState.state).get(fileId)\n\t\t\t\tif (progress === undefined || previousFileState === undefined || previousFileState.readyState !== 'uploading') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif (previousFileState.progress && Math.abs(progress - previousFileState.progress) < 0.01) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'uploading',\n\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\tuploader: previousFileState.uploader,\n\t\t\t\t\tabortController: previousFileState.abortController,\n\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\tmetadata: previousFileState.metadata,\n\t\t\t\t\tprogress: progress,\n\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tdefault:\n\t\t\tassertNever(action)\n\t}\n\tif (newState === undefined) {\n\t\treturn previousState\n\t}\n\treturn { ...previousState, state: newState }\n}\n"],"names":["toFileId","FileUploadError","assertNever"],"mappings":";;;;;AAOO,MAAM,4BAA4B,OAA+F;AAAA,EACvI,kCAAkB,QAAsB;AAAA,EACxC,2BAAW,IAAI;AAChB;AAEa,MAAA,oBAAoB,CAChC,eACA,WACoD;AACpD,MAAI,WAAgF;AAEpF,UAAQ,OAAO,MAAM;AAAA,IACpB,KAAK,cAAc;AAClB,iBAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,OAAO;AAE9C,SAAC,wBAAa,IAAI,IAAI,cAAc,KAAK,IAAG,IAAI,QAAQ;AAAA,UACvD,YAAY;AAAA,UACZ,iBAAiB,SAAS;AAAA,UAC1B,YAAY,SAAS;AAAA,UACrB,MAAM,SAAS;AAAA,QAAA,CACf;AAED,sBAAc,aAAa,IAAI,SAAS,MAAM,MAAM;AAAA,MACrD;AACA;AAAA,IACD;AAAA,IACA,KAAK,kBAAkB;AACtB,iBAAW,CAAC,UAAU,QAAQ,KAAK,OAAO,OAAO;AAC1C,cAAA,SAASA,SAAAA,SAAS,eAAe,QAAQ;AAC/C,cAAM,aAAa,YAAY,cAAc,OAAO,IAAI,MAAM;AAE9D,YAAI,cAAc,UAAa,UAAU,eAAe,gBAAgB;AACvE;AAAA,QACD;AAEA,SAAC,wBAAa,IAAI,IAAI,cAAc,KAAK,IAAG,IAAI,QAAQ;AAAA,UACvD,YAAY;AAAA,UACZ,iBAAiB,UAAU;AAAA,UAC3B,MAAM,UAAU;AAAA,UAChB,UAAU,SAAS;AAAA;AAAA,UACnB,YAAY,UAAU;AAAA,UACtB,UAAU;AAAA,UACV,UAAU,SAAS;AAAA,QAAA,CACnB;AAAA,MACF;AACA;AAAA,IACD;AAAA,IACA,KAAK,sBAAsB;AAC1B,iBAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQ;AACzC,cAAA,SAASA,SAAAA,SAAS,eAAe,QAAQ;AAC/C,cAAM,qBAAqB,YAAY,cAAc,OAAO,IAAI,MAAM;AACtE,YAAI,sBAAsB,UAAa,kBAAkB,eAAe,aAAa;AACpF;AAAA,QACD;AACA,SAAC,wBAAa,IAAI,IAAI,cAAc,KAAK,IAAG,IAAI,QAAQ;AAAA,UACvD,YAAY;AAAA,UACZ,MAAM,kBAAkB;AAAA,UACxB,UAAU,kBAAkB;AAAA,UAC5B,YAAY,kBAAkB;AAAA,UAC9B;AAAA,UACA,UAAU,kBAAkB;AAAA,QAAA,CAC5B;AAAA,MACF;AACA;AAAA,IACD;AAAA,IACA,KAAK,mBAAmB;AACZ,iBAAA,aAAa,OAAO,OAAO;AACjC,YAAA;AACA,YAAA;AAEA,YAAA,MAAM,QAAQ,SAAS,GAAG;AAC5B,WAAA,UAAU,QAAQ,IAAI;AAAA,QAAA,OACjB;AACK,qBAAA;AACA,qBAAA;AAAA,QACZ;AAEA,cAAM,SAA4B,CAAA;AAElC,YAAI,oBAAoBC,OAAAA,iBAAiB;AACxC,iBAAO,KAAK,QAAQ;AAAA,QACV,WAAA,MAAM,QAAQ,QAAQ,GAAG;AACnC,qBAAW,SAAS,UAAU;AAC7B,gBAAI,iBAAiBA,OAAAA,iBAAiB;AACrC,qBAAO,KAAK,KAAK;AAAA,YAClB;AAAA,UACD;AAAA,QACD;AAEM,cAAA,SAASD,SAAAA,SAAS,eAAe,QAAQ;AAC/C,cAAM,qBAAqB,YAAY,cAAc,OAAO,IAAI,MAAM;AACtE,YACC,sBAAsB,UACrB,kBAAkB,eAAe,kBAAkB,kBAAkB,eAAe,aACpF;AACD;AAAA,QACD;AACA,cAAM,WAAW,kBAAkB,eAAe,cAAc,kBAAkB,WAAW;AAC7F,cAAM,WAAW,kBAAkB,eAAe,cAAc,kBAAkB,WAAW;AAC1F,SAAC,wBAAa,IAAI,IAAI,cAAc,KAAK,IAAG,IAAI,QAAQ;AAAA,UACzD,YAAY;AAAA,UACZ,QAAQ,OAAO,SAAS,SAAS;AAAA,UACjC;AAAA,UACA,MAAM,kBAAkB;AAAA,UACxB;AAAA,UACA,YAAY,kBAAkB;AAAA,UAC9B;AAAA,QAAA,CACA;AAAA,MACH;AACA;AAAA,IACD;AAAA,IACA,KAAK,SAAS;AACF,iBAAA,YAAY,OAAO,OAAO;AAC9B,cAAA,SAASA,SAAAA,SAAS,eAAe,QAAQ;AAC/C,cAAM,aAAa,YAAY,cAAc,OAAO,IAAI,MAAM;AAE9D,YAAI,cAAc,QAAW;AAC5B;AAAA,QACD;AACI,YAAA,gBAAgB,UAAU,UAAU;AACxC,YAAI,UAAU,eAAe,kBAAkB,UAAU,eAAe,aAAa;AACpF,oBAAU,gBAAgB;QAC3B;AACA,SAAC,wBAAa,IAAI,IAAI,cAAc,KAAK,IAAG,OAAO,MAAM;AAAA,MAC1D;AACA;AAAA,IACD;AAAA,IACA,KAAK,wBAAwB;AAC5B,iBAAW,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,UAAU;AACjD,cAAA,SAASA,SAAAA,SAAS,eAAe,QAAQ;AAC/C,cAAM,qBAAqB,YAAY,cAAc,OAAO,IAAI,MAAM;AACtE,YAAI,aAAa,UAAa,sBAAsB,UAAa,kBAAkB,eAAe,aAAa;AAC9G;AAAA,QACD;AAEI,YAAA,kBAAkB,YAAY,KAAK,IAAI,WAAW,kBAAkB,QAAQ,IAAI,MAAM;AACzF;AAAA,QACD;AAEA,SAAC,wBAAa,IAAI,IAAI,cAAc,KAAK,IAAG,IAAI,QAAQ;AAAA,UACvD,YAAY;AAAA,UACZ,MAAM,kBAAkB;AAAA,UACxB,UAAU,kBAAkB;AAAA,UAC5B,iBAAiB,kBAAkB;AAAA,UACnC,YAAY,kBAAkB;AAAA,UAC9B,UAAU,kBAAkB;AAAA,UAC5B;AAAA,QAAA,CACA;AAAA,MACF;AACA;AAAA,IACD;AAAA,IACA;AACCE,gBAAA,YAAY,MAAM;AAAA,EACpB;AACA,MAAI,aAAa,QAAW;AACpB,WAAA;AAAA,EACR;AACA,SAAO,EAAE,GAAG,eAAe,OAAO,SAAS;AAC5C;;;"}
@@ -1,149 +0,0 @@
1
- import { FileUploadError } from "@contember/client";
2
- import { assertNever } from "@contember/utilities";
3
- import { toFileId } from "./toFileId.js";
4
- const initializeFileUploadState = () => ({
5
- fileIdByFile: /* @__PURE__ */ new WeakMap(),
6
- state: /* @__PURE__ */ new Map()
7
- });
8
- const fileUploadReducer = (previousState, action) => {
9
- let newState = void 0;
10
- switch (action.type) {
11
- case "initialize": {
12
- for (const [fileId, metadata] of action.files) {
13
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
14
- readyState: "initializing",
15
- abortController: metadata.abortController,
16
- previewUrl: metadata.previewUrl,
17
- file: metadata.file
18
- });
19
- previousState.fileIdByFile.set(metadata.file, fileId);
20
- }
21
- break;
22
- }
23
- case "startUploading": {
24
- for (const [fileOrId, metadata] of action.files) {
25
- const fileId = toFileId(previousState, fileOrId);
26
- const fileState = (newState ?? previousState.state).get(fileId);
27
- if (fileState === void 0 || fileState.readyState !== "initializing") {
28
- continue;
29
- }
30
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
31
- readyState: "uploading",
32
- abortController: fileState.abortController,
33
- file: fileState.file,
34
- metadata: metadata.metadata,
35
- // If the user didn't supply the metadata, then that's on them.
36
- previewUrl: fileState.previewUrl,
37
- progress: void 0,
38
- uploader: metadata.uploader
39
- });
40
- }
41
- break;
42
- }
43
- case "finishSuccessfully": {
44
- for (const [fileOrId, result] of action.result) {
45
- const fileId = toFileId(previousState, fileOrId);
46
- const previousFileState = (newState ?? previousState.state).get(fileId);
47
- if (previousFileState === void 0 || previousFileState.readyState !== "uploading") {
48
- continue;
49
- }
50
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
51
- readyState: "success",
52
- file: previousFileState.file,
53
- metadata: previousFileState.metadata,
54
- previewUrl: previousFileState.previewUrl,
55
- result,
56
- uploader: previousFileState.uploader
57
- });
58
- }
59
- break;
60
- }
61
- case "finishWithError": {
62
- for (const errorSpec of action.error) {
63
- let fileOrId;
64
- let rawError;
65
- if (Array.isArray(errorSpec)) {
66
- [fileOrId, rawError] = errorSpec;
67
- } else {
68
- fileOrId = errorSpec;
69
- rawError = void 0;
70
- }
71
- const errors = [];
72
- if (rawError instanceof FileUploadError) {
73
- errors.push(rawError);
74
- } else if (Array.isArray(rawError)) {
75
- for (const error of rawError) {
76
- if (error instanceof FileUploadError) {
77
- errors.push(error);
78
- }
79
- }
80
- }
81
- const fileId = toFileId(previousState, fileOrId);
82
- const previousFileState = (newState ?? previousState.state).get(fileId);
83
- if (previousFileState === void 0 || previousFileState.readyState !== "initializing" && previousFileState.readyState !== "uploading") {
84
- continue;
85
- }
86
- const uploader = previousFileState.readyState === "uploading" ? previousFileState.uploader : void 0;
87
- const metadata = previousFileState.readyState === "uploading" ? previousFileState.metadata : void 0;
88
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
89
- readyState: "error",
90
- errors: errors.length ? errors : void 0,
91
- rawError,
92
- file: previousFileState.file,
93
- metadata,
94
- previewUrl: previousFileState.previewUrl,
95
- uploader
96
- });
97
- }
98
- break;
99
- }
100
- case "purge": {
101
- for (const fileOrId of action.files) {
102
- const fileId = toFileId(previousState, fileOrId);
103
- const fileState = (newState ?? previousState.state).get(fileId);
104
- if (fileState === void 0) {
105
- continue;
106
- }
107
- URL.revokeObjectURL(fileState.previewUrl);
108
- if (fileState.readyState === "initializing" || fileState.readyState === "uploading") {
109
- fileState.abortController.abort();
110
- }
111
- (newState ?? (newState = new Map(previousState.state))).delete(fileId);
112
- }
113
- break;
114
- }
115
- case "updateUploadProgress": {
116
- for (const [fileOrId, { progress }] of action.progress) {
117
- const fileId = toFileId(previousState, fileOrId);
118
- const previousFileState = (newState ?? previousState.state).get(fileId);
119
- if (progress === void 0 || previousFileState === void 0 || previousFileState.readyState !== "uploading") {
120
- continue;
121
- }
122
- if (previousFileState.progress && Math.abs(progress - previousFileState.progress) < 0.01) {
123
- continue;
124
- }
125
- (newState ?? (newState = new Map(previousState.state))).set(fileId, {
126
- readyState: "uploading",
127
- file: previousFileState.file,
128
- uploader: previousFileState.uploader,
129
- abortController: previousFileState.abortController,
130
- previewUrl: previousFileState.previewUrl,
131
- metadata: previousFileState.metadata,
132
- progress
133
- });
134
- }
135
- break;
136
- }
137
- default:
138
- assertNever(action);
139
- }
140
- if (newState === void 0) {
141
- return previousState;
142
- }
143
- return { ...previousState, state: newState };
144
- };
145
- export {
146
- fileUploadReducer,
147
- initializeFileUploadState
148
- };
149
- //# sourceMappingURL=fileUploadReducer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fileUploadReducer.js","sources":["../../../src/upload/fileUploadReducer.ts"],"sourcesContent":["import { FileUploadError } from '@contember/client'\nimport { assertNever } from '@contember/utilities'\nimport type { FileId } from './FileId'\nimport type { FileUploadAction } from './FileUploadAction'\nimport type { FileUploadMultiTemporalState } from './FileUploadMultiTemporalState'\nimport { toFileId } from './toFileId'\n\nexport const initializeFileUploadState = <Result = unknown, Metadata = undefined>(): FileUploadMultiTemporalState<Result, Metadata> => ({\n\tfileIdByFile: new WeakMap<File, FileId>(),\n\tstate: new Map(),\n})\n\nexport const fileUploadReducer = <Result = unknown, Metadata = undefined>(\n\tpreviousState: FileUploadMultiTemporalState<Result, Metadata>,\n\taction: FileUploadAction<Result, Metadata>,\n): FileUploadMultiTemporalState<Result, Metadata> => {\n\tlet newState: undefined | FileUploadMultiTemporalState<Result, Metadata>['state'] = undefined\n\n\tswitch (action.type) {\n\t\tcase 'initialize': {\n\t\t\tfor (const [fileId, metadata] of action.files) {\n\t\t\t\t// Deliberately allowing starting a new upload with the same id\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'initializing',\n\t\t\t\t\tabortController: metadata.abortController,\n\t\t\t\t\tpreviewUrl: metadata.previewUrl,\n\t\t\t\t\tfile: metadata.file,\n\t\t\t\t})\n\t\t\t\t// Deliberately mutating\n\t\t\t\tpreviousState.fileIdByFile.set(metadata.file, fileId)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'startUploading': {\n\t\t\tfor (const [fileOrId, metadata] of action.files) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst fileState = (newState ?? previousState.state).get(fileId)\n\n\t\t\t\tif (fileState === undefined || fileState.readyState !== 'initializing') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'uploading',\n\t\t\t\t\tabortController: fileState.abortController,\n\t\t\t\t\tfile: fileState.file,\n\t\t\t\t\tmetadata: metadata.metadata!, // If the user didn't supply the metadata, then that's on them.\n\t\t\t\t\tpreviewUrl: fileState.previewUrl,\n\t\t\t\t\tprogress: undefined,\n\t\t\t\t\tuploader: metadata.uploader,\n\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'finishSuccessfully': {\n\t\t\tfor (const [fileOrId, result] of action.result) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst previousFileState = (newState ?? previousState.state).get(fileId)\n\t\t\t\tif (previousFileState === undefined || previousFileState.readyState !== 'uploading') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'success',\n\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\tmetadata: previousFileState.metadata,\n\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\tresult,\n\t\t\t\t\tuploader: previousFileState.uploader,\n\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'finishWithError': {\n\t\t\tfor (const errorSpec of action.error) {\n\t\t\t\tlet fileOrId: File | FileId\n\t\t\t\tlet rawError: unknown\n\n\t\t\t\tif (Array.isArray(errorSpec)) {\n\t\t\t\t\t[fileOrId, rawError] = errorSpec\n\t\t\t\t} else {\n\t\t\t\t\tfileOrId = errorSpec\n\t\t\t\t\trawError = undefined\n\t\t\t\t}\n\n\t\t\t\tconst errors: FileUploadError[] = []\n\n\t\t\t\tif (rawError instanceof FileUploadError) {\n\t\t\t\t\terrors.push(rawError)\n\t\t\t\t} else if (Array.isArray(rawError)) {\n\t\t\t\t\tfor (const error of rawError) {\n\t\t\t\t\t\tif (error instanceof FileUploadError) {\n\t\t\t\t\t\t\terrors.push(error)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst previousFileState = (newState ?? previousState.state).get(fileId)\n\t\t\t\tif (\n\t\t\t\t\tpreviousFileState === undefined ||\n\t\t\t\t\t(previousFileState.readyState !== 'initializing' && previousFileState.readyState !== 'uploading')\n\t\t\t\t) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst uploader = previousFileState.readyState === 'uploading' ? previousFileState.uploader : undefined\n\t\t\t\tconst metadata = previousFileState.readyState === 'uploading' ? previousFileState.metadata : undefined\n\t\t\t\t\t; (newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\t\treadyState: 'error',\n\t\t\t\t\t\terrors: errors.length ? errors : undefined,\n\t\t\t\t\t\trawError,\n\t\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\t\tuploader,\n\t\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'purge': {\n\t\t\tfor (const fileOrId of action.files) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst fileState = (newState ?? previousState.state).get(fileId)\n\n\t\t\t\tif (fileState === undefined) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tURL.revokeObjectURL(fileState.previewUrl)\n\t\t\t\tif (fileState.readyState === 'initializing' || fileState.readyState === 'uploading') {\n\t\t\t\t\tfileState.abortController.abort() // This is a bit naughty… We shouldn't do this from here.\n\t\t\t\t}\n\t\t\t\t(newState ??= new Map(previousState.state)).delete(fileId)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcase 'updateUploadProgress': {\n\t\t\tfor (const [fileOrId, { progress }] of action.progress) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst previousFileState = (newState ?? previousState.state).get(fileId)\n\t\t\t\tif (progress === undefined || previousFileState === undefined || previousFileState.readyState !== 'uploading') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif (previousFileState.progress && Math.abs(progress - previousFileState.progress) < 0.01) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t(newState ??= new Map(previousState.state)).set(fileId, {\n\t\t\t\t\treadyState: 'uploading',\n\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\tuploader: previousFileState.uploader,\n\t\t\t\t\tabortController: previousFileState.abortController,\n\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\tmetadata: previousFileState.metadata,\n\t\t\t\t\tprogress: progress,\n\t\t\t\t})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tdefault:\n\t\t\tassertNever(action)\n\t}\n\tif (newState === undefined) {\n\t\treturn previousState\n\t}\n\treturn { ...previousState, state: newState }\n}\n"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const toFileId = (state, fileOrId) => {
4
- if (fileOrId instanceof File) {
5
- return state.fileIdByFile.get(fileOrId);
6
- }
7
- return fileOrId;
8
- };
9
- exports.toFileId = toFileId;
10
- //# sourceMappingURL=toFileId.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toFileId.cjs","sources":["../../../src/upload/toFileId.ts"],"sourcesContent":["import type { FileId } from './FileId'\nimport type { FileUploadMultiTemporalState } from './FileUploadMultiTemporalState'\n\nexport const toFileId = <Result = unknown, Metadata = undefined>(\n\tstate: FileUploadMultiTemporalState<Result, Metadata>,\n\tfileOrId: File | FileId,\n): FileId => {\n\tif (fileOrId instanceof File) {\n\t\treturn state.fileIdByFile.get(fileOrId)! // Should we throw instead of the yolo \"!\"?\n\t}\n\treturn fileOrId\n}\n"],"names":[],"mappings":";;AAGa,MAAA,WAAW,CACvB,OACA,aACY;AACZ,MAAI,oBAAoB,MAAM;AACtB,WAAA,MAAM,aAAa,IAAI,QAAQ;AAAA,EACvC;AACO,SAAA;AACR;;"}
@@ -1,10 +0,0 @@
1
- const toFileId = (state, fileOrId) => {
2
- if (fileOrId instanceof File) {
3
- return state.fileIdByFile.get(fileOrId);
4
- }
5
- return fileOrId;
6
- };
7
- export {
8
- toFileId
9
- };
10
- //# sourceMappingURL=toFileId.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toFileId.js","sources":["../../../src/upload/toFileId.ts"],"sourcesContent":["import type { FileId } from './FileId'\nimport type { FileUploadMultiTemporalState } from './FileUploadMultiTemporalState'\n\nexport const toFileId = <Result = unknown, Metadata = undefined>(\n\tstate: FileUploadMultiTemporalState<Result, Metadata>,\n\tfileOrId: File | FileId,\n): FileId => {\n\tif (fileOrId instanceof File) {\n\t\treturn state.fileIdByFile.get(fileOrId)! // Should we throw instead of the yolo \"!\"?\n\t}\n\treturn fileOrId\n}\n"],"names":[],"mappings":"AAGa,MAAA,WAAW,CACvB,OACA,aACY;AACZ,MAAI,oBAAoB,MAAM;AACtB,WAAA,MAAM,aAAa,IAAI,QAAQ;AAAA,EACvC;AACO,SAAA;AACR;"}
@@ -1,166 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const client = require("@contember/client");
4
- const react = require("react");
5
- const fileUploadReducer = require("./fileUploadReducer.cjs");
6
- const useCurrentContentGraphQlClient = require("../content/useCurrentContentGraphQlClient.cjs");
7
- const useFileUpload = ({} = {}) => {
8
- const contentApiClient = useCurrentContentGraphQlClient.useCurrentContentGraphQlClient();
9
- const fileIdSeedRef = react.useRef(1);
10
- const [internalState, dispatch] = react.useReducer(fileUploadReducer.fileUploadReducer, void 0, fileUploadReducer.initializeFileUploadState);
11
- const defaultUploader = react.useMemo(() => new client.S3FileUploader(), []);
12
- const purgeUpload = react.useCallback((files) => {
13
- dispatch({
14
- type: "purge",
15
- files
16
- });
17
- }, []);
18
- const failUpload = react.useCallback((error) => {
19
- dispatch({
20
- type: "finishWithError",
21
- error
22
- });
23
- }, []);
24
- const previewUrls = react.useRef(/* @__PURE__ */ new Set());
25
- const fileIds = react.useRef(/* @__PURE__ */ new WeakMap());
26
- const filesWithMetadataById = react.useRef(/* @__PURE__ */ new Map());
27
- const initializeUpload = react.useCallback(
28
- (files) => {
29
- const newFileIds = /* @__PURE__ */ new Set();
30
- const fileWithMetadataByFileConfig = /* @__PURE__ */ new Map();
31
- for (const fileMaybeWithId of files) {
32
- const abortController = new AbortController();
33
- let fileId;
34
- let file;
35
- if (fileMaybeWithId instanceof File) {
36
- fileId = `__contember__file-${fileIdSeedRef.current++}`;
37
- file = fileMaybeWithId;
38
- } else {
39
- fileId = fileMaybeWithId[0];
40
- file = fileMaybeWithId[1];
41
- }
42
- abortController.signal.addEventListener("abort", () => {
43
- purgeUpload([fileId]);
44
- });
45
- const previewUrl = URL.createObjectURL(file);
46
- const fileWithMetadata = {
47
- previewUrl,
48
- abortController,
49
- file,
50
- fileId
51
- };
52
- fileWithMetadataByFileConfig.set(fileId, fileWithMetadata);
53
- newFileIds.add(fileId);
54
- previewUrls.current.add(previewUrl);
55
- fileIds.current.set(file, fileId);
56
- filesWithMetadataById.current.set(fileId, new WeakRef(fileWithMetadata));
57
- }
58
- if (fileWithMetadataByFileConfig.size === 0) {
59
- return fileWithMetadataByFileConfig;
60
- }
61
- if (newFileIds.size) {
62
- dispatch({
63
- type: "purge",
64
- files: newFileIds
65
- });
66
- }
67
- dispatch({
68
- type: "initialize",
69
- files: fileWithMetadataByFileConfig
70
- });
71
- return fileWithMetadataByFileConfig;
72
- },
73
- [purgeUpload]
74
- );
75
- const startUpload = react.useCallback(
76
- (files) => {
77
- const filesById = /* @__PURE__ */ new Map();
78
- const groupedByUploader = /* @__PURE__ */ new Map();
79
- for (const fileOrIdMaybeWithOptions of files) {
80
- let fileOrId;
81
- let options;
82
- if (Array.isArray(fileOrIdMaybeWithOptions)) {
83
- fileOrId = fileOrIdMaybeWithOptions[0];
84
- options = fileOrIdMaybeWithOptions[1];
85
- } else {
86
- fileOrId = fileOrIdMaybeWithOptions;
87
- options = {};
88
- }
89
- const { uploader = defaultUploader, metadata } = options;
90
- const fileId = fileOrId instanceof File ? fileIds.current.get(fileOrId) : fileOrId;
91
- const fileState = fileId ? filesWithMetadataById.current.get(fileId)?.deref() : void 0;
92
- if (fileId === void 0 || fileState === void 0) {
93
- throw new Error(
94
- `Trying to startUpload a file that hasn't been previously initialized. This will be possible in future, but isn't yet.`
95
- );
96
- }
97
- filesById.set(fileId, {
98
- uploader,
99
- metadata
100
- });
101
- let filesWithSameUploader = groupedByUploader.get(uploader);
102
- if (filesWithSameUploader === void 0) {
103
- groupedByUploader.set(uploader, filesWithSameUploader = /* @__PURE__ */ new Map());
104
- }
105
- filesWithSameUploader.set(fileState.file, {
106
- abortSignal: fileState.abortController.signal
107
- });
108
- }
109
- dispatch({
110
- type: "startUploading",
111
- files: filesById
112
- });
113
- for (const [uploader, filesForUpload] of groupedByUploader) {
114
- try {
115
- uploader.upload(filesForUpload, {
116
- onProgress: (progress) => {
117
- dispatch({
118
- type: "updateUploadProgress",
119
- progress
120
- });
121
- },
122
- onSuccess: (result) => {
123
- dispatch({
124
- type: "finishSuccessfully",
125
- result
126
- });
127
- },
128
- onError: (error) => {
129
- dispatch({
130
- type: "finishWithError",
131
- error
132
- });
133
- },
134
- contentApiClient
135
- });
136
- } catch (error) {
137
- dispatch({
138
- type: "finishWithError",
139
- error: Array.from(filesForUpload).map(([file]) => [file, error])
140
- });
141
- }
142
- }
143
- },
144
- [contentApiClient, defaultUploader]
145
- );
146
- const operations = react.useMemo(
147
- () => ({
148
- failUpload,
149
- initializeUpload,
150
- purgeUpload,
151
- startUpload
152
- }),
153
- [failUpload, initializeUpload, purgeUpload, startUpload]
154
- );
155
- react.useEffect(
156
- () => () => {
157
- for (const previewUrl of Array.from(previewUrls.current)) {
158
- URL.revokeObjectURL(previewUrl);
159
- }
160
- },
161
- []
162
- );
163
- return [internalState.state, operations];
164
- };
165
- exports.useFileUpload = useFileUpload;
166
- //# sourceMappingURL=useFileUpload.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useFileUpload.cjs","sources":["../../../src/upload/useFileUpload.ts"],"sourcesContent":["import { FileUploader, S3FileUploader, UploadedFileMetadata } from '@contember/client'\nimport { Reducer, useCallback, useEffect, useMemo, useReducer, useRef } from 'react'\nimport { useCurrentContentGraphQlClient } from '../content'\nimport type { FileId } from './FileId'\nimport type { FileUploadAction } from './FileUploadAction'\nimport type { FileUploadCompoundState } from './FileUploadCompoundState'\nimport type { FileUploadMetadata } from './FileUploadMetadata'\nimport type { FileUploadMultiTemporalState } from './FileUploadMultiTemporalState'\nimport type {\n\tPurgeUpload,\n\tFileUploadOperations,\n\tInitializeUpload,\n\tStartUpload,\n\tStartUploadFileOptions,\n\tFailUpload,\n} from './FileUploadOperations'\nimport { fileUploadReducer, initializeFileUploadState } from './fileUploadReducer'\nimport type { FileWithMetadata } from './FileWithMetadata'\n\nexport type FileUpload<Result = unknown, Metadata = undefined> = [\n\tFileUploadCompoundState<Result, Metadata>,\n\tFileUploadOperations<Metadata>,\n]\n\nexport interface FileUploadOptions {\n}\n\nexport const useFileUpload = <Result = unknown, Metadata = undefined>({}: FileUploadOptions = {}): FileUpload<Result, Metadata> => {\n\tconst contentApiClient = useCurrentContentGraphQlClient()\n\n\tconst fileIdSeedRef = useRef(1)\n\n\tconst [internalState, dispatch] = useReducer<\n\t\tReducer<FileUploadMultiTemporalState<Result, Metadata>, FileUploadAction<Result, Metadata>>,\n\t\tundefined\n\t>(fileUploadReducer, undefined, initializeFileUploadState)\n\n\tconst defaultUploader = useMemo(() => new S3FileUploader(), [])\n\n\tconst purgeUpload = useCallback<PurgeUpload>(files => {\n\t\tdispatch({\n\t\t\ttype: 'purge',\n\t\t\tfiles,\n\t\t})\n\t}, [])\n\tconst failUpload = useCallback<FailUpload>(error => {\n\t\tdispatch({\n\t\t\ttype: 'finishWithError',\n\t\t\terror,\n\t\t})\n\t}, [])\n\n\tconst previewUrls = useRef(new Set<string>())\n\tconst fileIds = useRef(new WeakMap<File, FileId>())\n\tconst filesWithMetadataById = useRef(new Map<FileId, WeakRef<FileWithMetadata>>)\n\n\tconst initializeUpload = useCallback<InitializeUpload>(\n\t\tfiles => {\n\t\t\tconst newFileIds = new Set<FileId>()\n\t\t\tconst fileWithMetadataByFileConfig = new Map<FileId, FileWithMetadata>()\n\n\t\t\tfor (const fileMaybeWithId of files) {\n\t\t\t\tconst abortController = new AbortController()\n\n\t\t\t\tlet fileId: FileId\n\t\t\t\tlet file: File\n\n\t\t\t\tif (fileMaybeWithId instanceof File) {\n\t\t\t\t\tfileId = `__contember__file-${fileIdSeedRef.current++}`\n\t\t\t\t\tfile = fileMaybeWithId\n\t\t\t\t} else {\n\t\t\t\t\tfileId = fileMaybeWithId[0]\n\t\t\t\t\tfile = fileMaybeWithId[1]\n\t\t\t\t}\n\n\t\t\t\tabortController.signal.addEventListener('abort', () => {\n\t\t\t\t\tpurgeUpload([fileId])\n\t\t\t\t})\n\n\t\t\t\tconst previewUrl = URL.createObjectURL(file)\n\t\t\t\tconst fileWithMetadata: FileWithMetadata = {\n\t\t\t\t\tpreviewUrl: previewUrl,\n\t\t\t\t\tabortController,\n\t\t\t\t\tfile,\n\t\t\t\t\tfileId,\n\t\t\t\t}\n\t\t\t\tfileWithMetadataByFileConfig.set(fileId, fileWithMetadata)\n\n\t\t\t\tnewFileIds.add(fileId)\n\n\t\t\t\tpreviewUrls.current.add(previewUrl)\n\t\t\t\tfileIds.current.set(file, fileId)\n\t\t\t\tfilesWithMetadataById.current.set(fileId, new WeakRef(fileWithMetadata))\n\t\t\t}\n\t\t\tif (fileWithMetadataByFileConfig.size === 0) {\n\t\t\t\treturn fileWithMetadataByFileConfig\n\t\t\t}\n\n\t\t\tif (newFileIds.size) {\n\t\t\t\tdispatch({\n\t\t\t\t\ttype: 'purge',\n\t\t\t\t\tfiles: newFileIds,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tdispatch({\n\t\t\t\ttype: 'initialize',\n\t\t\t\tfiles: fileWithMetadataByFileConfig,\n\t\t\t})\n\n\t\t\treturn fileWithMetadataByFileConfig\n\t\t},\n\t\t[purgeUpload],\n\t)\n\tconst startUpload = useCallback<StartUpload<Metadata>>(\n\t\tfiles => {\n\t\t\tconst filesById = new Map<FileId, FileUploadMetadata<Metadata>>()\n\t\t\tconst groupedByUploader: Map<FileUploader, Map<File, UploadedFileMetadata>> = new Map()\n\n\t\t\tfor (const fileOrIdMaybeWithOptions of files) {\n\t\t\t\tlet fileOrId: File | FileId\n\t\t\t\tlet options: StartUploadFileOptions<Metadata>\n\n\t\t\t\tif (Array.isArray(fileOrIdMaybeWithOptions)) {\n\t\t\t\t\tfileOrId = fileOrIdMaybeWithOptions[0]\n\t\t\t\t\toptions = fileOrIdMaybeWithOptions[1]\n\t\t\t\t} else {\n\t\t\t\t\tfileOrId = fileOrIdMaybeWithOptions\n\t\t\t\t\toptions = {}\n\t\t\t\t}\n\t\t\t\tconst { uploader = defaultUploader, metadata } = options\n\n\t\t\t\tconst fileId = fileOrId instanceof File ? fileIds.current.get(fileOrId) : fileOrId\n\t\t\t\tconst fileState = fileId ? filesWithMetadataById.current.get(fileId)?.deref() : undefined\n\n\t\t\t\tif (fileId === undefined || fileState === undefined) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Trying to startUpload a file that hasn't been previously initialized. ` +\n\t\t\t\t\t\t\t`This will be possible in future, but isn't yet.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\n\n\t\t\t\tfilesById.set(fileId, {\n\t\t\t\t\tuploader,\n\t\t\t\t\tmetadata,\n\t\t\t\t})\n\n\t\t\t\tlet filesWithSameUploader = groupedByUploader.get(uploader)\n\t\t\t\tif (filesWithSameUploader === undefined) {\n\t\t\t\t\tgroupedByUploader.set(uploader, (filesWithSameUploader = new Map()))\n\t\t\t\t}\n\t\t\t\tfilesWithSameUploader.set(fileState.file, {\n\t\t\t\t\tabortSignal: fileState.abortController.signal,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tdispatch({\n\t\t\t\ttype: 'startUploading',\n\t\t\t\tfiles: filesById,\n\t\t\t})\n\n\t\t\tfor (const [uploader, filesForUpload] of groupedByUploader) {\n\t\t\t\ttry {\n\t\t\t\t\tuploader.upload(filesForUpload, {\n\t\t\t\t\t\tonProgress: progress => {\n\t\t\t\t\t\t\tdispatch({\n\t\t\t\t\t\t\t\ttype: 'updateUploadProgress',\n\t\t\t\t\t\t\t\tprogress,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonSuccess: result => {\n\t\t\t\t\t\t\tdispatch({\n\t\t\t\t\t\t\t\ttype: 'finishSuccessfully',\n\t\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonError: error => {\n\t\t\t\t\t\t\tdispatch({\n\t\t\t\t\t\t\t\ttype: 'finishWithError',\n\t\t\t\t\t\t\t\terror,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcontentApiClient,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tdispatch({\n\t\t\t\t\t\ttype: 'finishWithError',\n\t\t\t\t\t\terror: Array.from(filesForUpload).map(([file]) => [file, error]),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[contentApiClient, defaultUploader],\n\t)\n\n\tconst operations = useMemo<FileUploadOperations<Metadata>>(\n\t\t() => ({\n\t\t\tfailUpload,\n\t\t\tinitializeUpload,\n\t\t\tpurgeUpload,\n\t\t\tstartUpload,\n\t\t}),\n\t\t[failUpload, initializeUpload, purgeUpload, startUpload],\n\t)\n\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tfor (const previewUrl of Array.from(previewUrls.current)) {\n\t\t\t\tURL.revokeObjectURL(previewUrl)\n\t\t\t}\n\t\t},\n\t\t[],\n\t)\n\n\treturn [internalState.state, operations]\n}\n"],"names":["useCurrentContentGraphQlClient","useRef","useReducer","fileUploadReducer","initializeFileUploadState","useMemo","S3FileUploader","useCallback","useEffect"],"mappings":"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"}