@contember/react-client 0.7.0-alpha.20

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 (168) hide show
  1. package/LICENSE +186 -0
  2. package/dist/development/ClientError.js +5 -0
  3. package/dist/development/ClientError.js.map +1 -0
  4. package/dist/development/ContemberClient.js +30 -0
  5. package/dist/development/ContemberClient.js.map +1 -0
  6. package/dist/development/apiRequest/apiRequestReducer.js +33 -0
  7. package/dist/development/apiRequest/apiRequestReducer.js.map +1 -0
  8. package/dist/development/apiRequest/useApiRequest.js +43 -0
  9. package/dist/development/apiRequest/useApiRequest.js.map +1 -0
  10. package/dist/development/auth/SessionTokenContext.js +6 -0
  11. package/dist/development/auth/SessionTokenContext.js.map +1 -0
  12. package/dist/development/auth/useLoginRequest.js +18 -0
  13. package/dist/development/auth/useLoginRequest.js.map +1 -0
  14. package/dist/development/auth/useSessionToken.js +7 -0
  15. package/dist/development/auth/useSessionToken.js.map +1 -0
  16. package/dist/development/components/RichTextRenderer/ElementRenderer.js +25 -0
  17. package/dist/development/components/RichTextRenderer/ElementRenderer.js.map +1 -0
  18. package/dist/development/components/RichTextRenderer/LeafRenderer.js +21 -0
  19. package/dist/development/components/RichTextRenderer/LeafRenderer.js.map +1 -0
  20. package/dist/development/components/RichTextRenderer/RenderElementFallback.js +107 -0
  21. package/dist/development/components/RichTextRenderer/RenderElementFallback.js.map +1 -0
  22. package/dist/development/components/RichTextRenderer/RenderLeafFallback.js +36 -0
  23. package/dist/development/components/RichTextRenderer/RenderLeafFallback.js.map +1 -0
  24. package/dist/development/components/RichTextRenderer/RichTextRenderMetadataContext.js +14 -0
  25. package/dist/development/components/RichTextRenderer/RichTextRenderMetadataContext.js.map +1 -0
  26. package/dist/development/components/RichTextRenderer/RichTextRenderer.js +91 -0
  27. package/dist/development/components/RichTextRenderer/RichTextRenderer.js.map +1 -0
  28. package/dist/development/components/RichTextRenderer/RichTextRendererError.js +5 -0
  29. package/dist/development/components/RichTextRenderer/RichTextRendererError.js.map +1 -0
  30. package/dist/development/components/RichTextRenderer/defaultDeserialize.js +13 -0
  31. package/dist/development/components/RichTextRenderer/defaultDeserialize.js.map +1 -0
  32. package/dist/development/components/RichTextRenderer/renderChildren.js +29 -0
  33. package/dist/development/components/RichTextRenderer/renderChildren.js.map +1 -0
  34. package/dist/development/components/RichTextRenderer/resolveRichTextElementMetadata.js +27 -0
  35. package/dist/development/components/RichTextRenderer/resolveRichTextElementMetadata.js.map +1 -0
  36. package/dist/development/config/ApiBaseUrlContext.js +6 -0
  37. package/dist/development/config/ApiBaseUrlContext.js.map +1 -0
  38. package/dist/development/config/LoginTokenContext.js +6 -0
  39. package/dist/development/config/LoginTokenContext.js.map +1 -0
  40. package/dist/development/config/useApiBaseUrl.js +7 -0
  41. package/dist/development/config/useApiBaseUrl.js.map +1 -0
  42. package/dist/development/config/useLoginToken.js +7 -0
  43. package/dist/development/config/useLoginToken.js.map +1 -0
  44. package/dist/development/content/useContentApiRequest.js +7 -0
  45. package/dist/development/content/useContentApiRequest.js.map +1 -0
  46. package/dist/development/content/useContentGraphQlClient.js +7 -0
  47. package/dist/development/content/useContentGraphQlClient.js.map +1 -0
  48. package/dist/development/content/useCurrentContentGraphQlClient.js +19 -0
  49. package/dist/development/content/useCurrentContentGraphQlClient.js.map +1 -0
  50. package/dist/development/index.js +31 -0
  51. package/dist/development/index.js.map +1 -0
  52. package/dist/development/project/ProjectSlugContext.js +6 -0
  53. package/dist/development/project/ProjectSlugContext.js.map +1 -0
  54. package/dist/development/project/StageSlugContext.js +6 -0
  55. package/dist/development/project/StageSlugContext.js.map +1 -0
  56. package/dist/development/project/useProjectSlug.js +7 -0
  57. package/dist/development/project/useProjectSlug.js.map +1 -0
  58. package/dist/development/project/useStageSlug.js +7 -0
  59. package/dist/development/project/useStageSlug.js.map +1 -0
  60. package/dist/development/system/useCurrentSystemGraphQlClient.js +14 -0
  61. package/dist/development/system/useCurrentSystemGraphQlClient.js.map +1 -0
  62. package/dist/development/system/useDiffQuery.js +17 -0
  63. package/dist/development/system/useDiffQuery.js.map +1 -0
  64. package/dist/development/system/useReleaseTreeMutation.js +17 -0
  65. package/dist/development/system/useReleaseTreeMutation.js.map +1 -0
  66. package/dist/development/system/useSystemApiRequest.js +7 -0
  67. package/dist/development/system/useSystemApiRequest.js.map +1 -0
  68. package/dist/development/system/useSystemGraphQlClient.js +7 -0
  69. package/dist/development/system/useSystemGraphQlClient.js.map +1 -0
  70. package/dist/development/tenant/useTenantApiRequest.js +7 -0
  71. package/dist/development/tenant/useTenantApiRequest.js.map +1 -0
  72. package/dist/development/tenant/useTenantGraphQlClient.js +7 -0
  73. package/dist/development/tenant/useTenantGraphQlClient.js.map +1 -0
  74. package/dist/development/upload/fileUploadReducer.js +162 -0
  75. package/dist/development/upload/fileUploadReducer.js.map +1 -0
  76. package/dist/development/upload/toFileId.js +9 -0
  77. package/dist/development/upload/toFileId.js.map +1 -0
  78. package/dist/development/upload/useFileUpload.js +192 -0
  79. package/dist/development/upload/useFileUpload.js.map +1 -0
  80. package/dist/development/useGraphQlClient.js +13 -0
  81. package/dist/development/useGraphQlClient.js.map +1 -0
  82. package/dist/development/utils/assertNever.js +6 -0
  83. package/dist/development/utils/assertNever.js.map +1 -0
  84. package/dist/production/ClientError.js +4 -0
  85. package/dist/production/ClientError.js.map +1 -0
  86. package/dist/production/ContemberClient.js +28 -0
  87. package/dist/production/ContemberClient.js.map +1 -0
  88. package/dist/production/apiRequest/apiRequestReducer.js +32 -0
  89. package/dist/production/apiRequest/apiRequestReducer.js.map +1 -0
  90. package/dist/production/apiRequest/useApiRequest.js +41 -0
  91. package/dist/production/apiRequest/useApiRequest.js.map +1 -0
  92. package/dist/production/auth/SessionTokenContext.js +4 -0
  93. package/dist/production/auth/SessionTokenContext.js.map +1 -0
  94. package/dist/production/auth/useLoginRequest.js +16 -0
  95. package/dist/production/auth/useLoginRequest.js.map +1 -0
  96. package/dist/production/auth/useSessionToken.js +5 -0
  97. package/dist/production/auth/useSessionToken.js.map +1 -0
  98. package/dist/production/components/RichTextRenderer/ElementRenderer.js +23 -0
  99. package/dist/production/components/RichTextRenderer/ElementRenderer.js.map +1 -0
  100. package/dist/production/components/RichTextRenderer/LeafRenderer.js +19 -0
  101. package/dist/production/components/RichTextRenderer/LeafRenderer.js.map +1 -0
  102. package/dist/production/components/RichTextRenderer/RenderElementFallback.js +104 -0
  103. package/dist/production/components/RichTextRenderer/RenderElementFallback.js.map +1 -0
  104. package/dist/production/components/RichTextRenderer/RenderLeafFallback.js +34 -0
  105. package/dist/production/components/RichTextRenderer/RenderLeafFallback.js.map +1 -0
  106. package/dist/production/components/RichTextRenderer/RichTextRenderMetadataContext.js +12 -0
  107. package/dist/production/components/RichTextRenderer/RichTextRenderMetadataContext.js.map +1 -0
  108. package/dist/production/components/RichTextRenderer/RichTextRenderer.js +89 -0
  109. package/dist/production/components/RichTextRenderer/RichTextRenderer.js.map +1 -0
  110. package/dist/production/components/RichTextRenderer/RichTextRendererError.js +4 -0
  111. package/dist/production/components/RichTextRenderer/RichTextRendererError.js.map +1 -0
  112. package/dist/production/components/RichTextRenderer/defaultDeserialize.js +12 -0
  113. package/dist/production/components/RichTextRenderer/defaultDeserialize.js.map +1 -0
  114. package/dist/production/components/RichTextRenderer/renderChildren.js +27 -0
  115. package/dist/production/components/RichTextRenderer/renderChildren.js.map +1 -0
  116. package/dist/production/components/RichTextRenderer/resolveRichTextElementMetadata.js +25 -0
  117. package/dist/production/components/RichTextRenderer/resolveRichTextElementMetadata.js.map +1 -0
  118. package/dist/production/config/ApiBaseUrlContext.js +4 -0
  119. package/dist/production/config/ApiBaseUrlContext.js.map +1 -0
  120. package/dist/production/config/LoginTokenContext.js +4 -0
  121. package/dist/production/config/LoginTokenContext.js.map +1 -0
  122. package/dist/production/config/useApiBaseUrl.js +5 -0
  123. package/dist/production/config/useApiBaseUrl.js.map +1 -0
  124. package/dist/production/config/useLoginToken.js +5 -0
  125. package/dist/production/config/useLoginToken.js.map +1 -0
  126. package/dist/production/content/useContentApiRequest.js +5 -0
  127. package/dist/production/content/useContentApiRequest.js.map +1 -0
  128. package/dist/production/content/useContentGraphQlClient.js +5 -0
  129. package/dist/production/content/useContentGraphQlClient.js.map +1 -0
  130. package/dist/production/content/useCurrentContentGraphQlClient.js +17 -0
  131. package/dist/production/content/useCurrentContentGraphQlClient.js.map +1 -0
  132. package/dist/production/index.js +31 -0
  133. package/dist/production/index.js.map +1 -0
  134. package/dist/production/project/ProjectSlugContext.js +4 -0
  135. package/dist/production/project/ProjectSlugContext.js.map +1 -0
  136. package/dist/production/project/StageSlugContext.js +4 -0
  137. package/dist/production/project/StageSlugContext.js.map +1 -0
  138. package/dist/production/project/useProjectSlug.js +5 -0
  139. package/dist/production/project/useProjectSlug.js.map +1 -0
  140. package/dist/production/project/useStageSlug.js +5 -0
  141. package/dist/production/project/useStageSlug.js.map +1 -0
  142. package/dist/production/system/useCurrentSystemGraphQlClient.js +12 -0
  143. package/dist/production/system/useCurrentSystemGraphQlClient.js.map +1 -0
  144. package/dist/production/system/useDiffQuery.js +15 -0
  145. package/dist/production/system/useDiffQuery.js.map +1 -0
  146. package/dist/production/system/useReleaseTreeMutation.js +15 -0
  147. package/dist/production/system/useReleaseTreeMutation.js.map +1 -0
  148. package/dist/production/system/useSystemApiRequest.js +5 -0
  149. package/dist/production/system/useSystemApiRequest.js.map +1 -0
  150. package/dist/production/system/useSystemGraphQlClient.js +5 -0
  151. package/dist/production/system/useSystemGraphQlClient.js.map +1 -0
  152. package/dist/production/tenant/useTenantApiRequest.js +5 -0
  153. package/dist/production/tenant/useTenantApiRequest.js.map +1 -0
  154. package/dist/production/tenant/useTenantGraphQlClient.js +5 -0
  155. package/dist/production/tenant/useTenantGraphQlClient.js.map +1 -0
  156. package/dist/production/upload/fileUploadReducer.js +160 -0
  157. package/dist/production/upload/fileUploadReducer.js.map +1 -0
  158. package/dist/production/upload/toFileId.js +8 -0
  159. package/dist/production/upload/toFileId.js.map +1 -0
  160. package/dist/production/upload/useFileUpload.js +190 -0
  161. package/dist/production/upload/useFileUpload.js.map +1 -0
  162. package/dist/production/useGraphQlClient.js +11 -0
  163. package/dist/production/useGraphQlClient.js.map +1 -0
  164. package/dist/production/utils/assertNever.js +5 -0
  165. package/dist/production/utils/assertNever.js.map +1 -0
  166. package/dist/react-client.d.ts +370 -0
  167. package/package.json +31 -0
  168. package/readme.md +22 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCurrentSystemGraphQlClient.js","sources":["../../../src/system/useCurrentSystemGraphQlClient.ts"],"sourcesContent":["import type { GraphQlClient } from '@contember/client'\nimport { ClientError } from '../ClientError'\nimport { useProjectSlug } from '../project'\nimport { useSystemGraphQlClient } from './useSystemGraphQlClient'\n\nexport const useCurrentSystemGraphQlClient = (): GraphQlClient => {\n\tconst projectSlug = useProjectSlug()\n\n\tif (projectSlug === undefined) {\n\t\tthrow new ClientError(`Cannot contact the system API: undefined project slug.`)\n\t}\n\treturn useSystemGraphQlClient(projectSlug)\n}\n"],"names":[],"mappings":";;;;MAKa,gCAAgC,MAAqB;AACjE,QAAM,cAAc;AAEpB,MAAI,gBAAgB,QAAW;AAC9B,UAAM,IAAI,YAAY;AAAA;AAEvB,SAAO,uBAAuB;AAAA;;;;"}
@@ -0,0 +1,17 @@
1
+ import { diffQuery } from '@contember/client';
2
+ import { useCallback } from 'react';
3
+ import { useSystemApiRequest } from './useSystemApiRequest.js';
4
+ import { useStageSlug } from '../project/useStageSlug.js';
5
+
6
+ const useDiffQuery = () => {
7
+ const [requestState, sendRequest] = useSystemApiRequest();
8
+ const stage = useStageSlug();
9
+ const sendQuery = useCallback((treeFilter) => sendRequest(diffQuery, {
10
+ stage,
11
+ filter: treeFilter
12
+ }), [stage, sendRequest]);
13
+ return [requestState, sendQuery];
14
+ };
15
+
16
+ export { useDiffQuery };
17
+ //# sourceMappingURL=useDiffQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDiffQuery.js","sources":["../../../src/system/useDiffQuery.ts"],"sourcesContent":["import { diffQuery, DiffQueryResponse, TreeFilter } from '@contember/client'\nimport { useCallback } from 'react'\nimport type { ApiRequestState } from '../apiRequest'\nimport { useStageSlug } from '../project'\nimport { useSystemApiRequest } from './useSystemApiRequest'\n\nexport const useDiffQuery = (): [\n\tApiRequestState<DiffQueryResponse>,\n\t(treeFilter: TreeFilter[]) => Promise<DiffQueryResponse>,\n] => {\n\tconst [requestState, sendRequest] = useSystemApiRequest<DiffQueryResponse>()\n\tconst stage = useStageSlug()\n\tconst sendQuery = useCallback(\n\t\t(treeFilter: TreeFilter[]) =>\n\t\t\tsendRequest(diffQuery, {\n\t\t\t\tstage,\n\t\t\t\tfilter: treeFilter,\n\t\t\t}),\n\t\t[stage, sendRequest],\n\t)\n\n\treturn [requestState, sendQuery]\n}\n"],"names":[],"mappings":";;;;;MAMa,eAAe,MAGvB;AACJ,QAAM,CAAC,cAAc,eAAe;AACpC,QAAM,QAAQ;AACd,QAAM,YAAY,YACjB,CAAC,eACA,YAAY,WAAW;AAAA,IACtB;AAAA,IACA,QAAQ;AAAA,MAEV,CAAC,OAAO;AAGT,SAAO,CAAC,cAAc;AAAA;;;;"}
@@ -0,0 +1,17 @@
1
+ import { releaseTreeMutation } from '@contember/client';
2
+ import { useCallback } from 'react';
3
+ import { useSystemApiRequest } from './useSystemApiRequest.js';
4
+ import { useStageSlug } from '../project/useStageSlug.js';
5
+
6
+ const useReleaseTreeMutation = () => {
7
+ const [requestState, sendRequest] = useSystemApiRequest();
8
+ const stage = useStageSlug();
9
+ const sendMutation = useCallback((treeFilter) => sendRequest(releaseTreeMutation, {
10
+ stage,
11
+ filter: treeFilter
12
+ }), [stage, sendRequest]);
13
+ return [requestState, sendMutation];
14
+ };
15
+
16
+ export { useReleaseTreeMutation };
17
+ //# sourceMappingURL=useReleaseTreeMutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReleaseTreeMutation.js","sources":["../../../src/system/useReleaseTreeMutation.ts"],"sourcesContent":["import { releaseTreeMutation, ReleaseTreeMutationResponse, TreeFilter } from '@contember/client'\nimport { useCallback } from 'react'\nimport type { ApiRequestState } from '../apiRequest'\nimport { useStageSlug } from '../project'\nimport { useSystemApiRequest } from './useSystemApiRequest'\n\nexport const useReleaseTreeMutation = (): [\n\tApiRequestState<ReleaseTreeMutationResponse>,\n\t(treeFilter: TreeFilter[]) => Promise<ReleaseTreeMutationResponse>,\n] => {\n\tconst [requestState, sendRequest] = useSystemApiRequest<ReleaseTreeMutationResponse>()\n\tconst stage = useStageSlug()\n\tconst sendMutation = useCallback(\n\t\t(treeFilter: TreeFilter[]) =>\n\t\t\tsendRequest(releaseTreeMutation, {\n\t\t\t\tstage,\n\t\t\t\tfilter: treeFilter,\n\t\t\t}),\n\t\t[stage, sendRequest],\n\t)\n\n\treturn [requestState, sendMutation]\n}\n"],"names":[],"mappings":";;;;;MAMa,yBAAyB,MAGjC;AACJ,QAAM,CAAC,cAAc,eAAe;AACpC,QAAM,QAAQ;AACd,QAAM,eAAe,YACpB,CAAC,eACA,YAAY,qBAAqB;AAAA,IAChC;AAAA,IACA,QAAQ;AAAA,MAEV,CAAC,OAAO;AAGT,SAAO,CAAC,cAAc;AAAA;;;;"}
@@ -0,0 +1,7 @@
1
+ import { useCurrentSystemGraphQlClient } from './useCurrentSystemGraphQlClient.js';
2
+ import { useApiRequest } from '../apiRequest/useApiRequest.js';
3
+
4
+ const useSystemApiRequest = () => useApiRequest(useCurrentSystemGraphQlClient());
5
+
6
+ export { useSystemApiRequest };
7
+ //# sourceMappingURL=useSystemApiRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSystemApiRequest.js","sources":["../../../src/system/useSystemApiRequest.ts"],"sourcesContent":["import type { UseApiRequestResult } from '../apiRequest'\nimport { useApiRequest } from '../apiRequest'\nimport { useCurrentSystemGraphQlClient } from './useCurrentSystemGraphQlClient'\n\nexport const useSystemApiRequest = <SuccessData>(): UseApiRequestResult<SuccessData> =>\n\tuseApiRequest<SuccessData>(useCurrentSystemGraphQlClient())\n"],"names":[],"mappings":";;;MAIa,sBAAsB,MAClC,cAA2B;;;;"}
@@ -0,0 +1,7 @@
1
+ import { formatSystemApiRelativeUrl } from '@contember/client';
2
+ import { useGraphQlClient } from '../useGraphQlClient.js';
3
+
4
+ const useSystemGraphQlClient = (projectSlug) => useGraphQlClient(formatSystemApiRelativeUrl(projectSlug));
5
+
6
+ export { useSystemGraphQlClient };
7
+ //# sourceMappingURL=useSystemGraphQlClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSystemGraphQlClient.js","sources":["../../../src/system/useSystemGraphQlClient.ts"],"sourcesContent":["import { formatSystemApiRelativeUrl } from '@contember/client'\nimport { useGraphQlClient } from '../useGraphQlClient'\n\nexport const useSystemGraphQlClient = (projectSlug: string) => useGraphQlClient(formatSystemApiRelativeUrl(projectSlug))\n"],"names":[],"mappings":";;;MAGa,yBAAyB,CAAC,gBAAwB,iBAAiB,2BAA2B;;;;"}
@@ -0,0 +1,7 @@
1
+ import { useTenantGraphQlClient } from './useTenantGraphQlClient.js';
2
+ import { useApiRequest } from '../apiRequest/useApiRequest.js';
3
+
4
+ const useTenantApiRequest = () => useApiRequest(useTenantGraphQlClient());
5
+
6
+ export { useTenantApiRequest };
7
+ //# sourceMappingURL=useTenantApiRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTenantApiRequest.js","sources":["../../../src/tenant/useTenantApiRequest.ts"],"sourcesContent":["import type { UseApiRequestResult } from '../apiRequest'\nimport { useApiRequest } from '../apiRequest'\nimport { useTenantGraphQlClient } from './useTenantGraphQlClient'\n\nexport const useTenantApiRequest = <SuccessData>(): UseApiRequestResult<SuccessData> =>\n\tuseApiRequest<SuccessData>(useTenantGraphQlClient())\n"],"names":[],"mappings":";;;MAIa,sBAAsB,MAClC,cAA2B;;;;"}
@@ -0,0 +1,7 @@
1
+ import { tenantApiRelativeUrl } from '@contember/client';
2
+ import { useGraphQlClient } from '../useGraphQlClient.js';
3
+
4
+ const useTenantGraphQlClient = () => useGraphQlClient(tenantApiRelativeUrl);
5
+
6
+ export { useTenantGraphQlClient };
7
+ //# sourceMappingURL=useTenantGraphQlClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTenantGraphQlClient.js","sources":["../../../src/tenant/useTenantGraphQlClient.ts"],"sourcesContent":["import { tenantApiRelativeUrl } from '@contember/client'\nimport { useGraphQlClient } from '../useGraphQlClient'\n\nexport const useTenantGraphQlClient = () => useGraphQlClient(tenantApiRelativeUrl)\n"],"names":[],"mappings":";;;MAGa,yBAAyB,MAAM,iBAAiB;;;;"}
@@ -0,0 +1,162 @@
1
+ import { FileUploadError } from '@contember/client';
2
+ import { toFileId } from './toFileId.js';
3
+ import { assertNever } from '../utils/assertNever.js';
4
+
5
+ const initializeFileUploadState = () => ({
6
+ lastUpdateTime: 0,
7
+ fileIdByFile: new WeakMap(),
8
+ liveState: new Map(),
9
+ publicState: new Map(),
10
+ isLiveStateDirty: false
11
+ });
12
+ const fileUploadReducer = (previousState, action) => {
13
+ const publishNewState = () => ({
14
+ publicState: previousState.liveState,
15
+ fileIdByFile: previousState.fileIdByFile,
16
+ lastUpdateTime: previousState.lastUpdateTime,
17
+ isLiveStateDirty: false,
18
+ liveState: new Map(previousState.liveState)
19
+ });
20
+ const getNewDirtyState = () => ({
21
+ fileIdByFile: previousState.fileIdByFile,
22
+ liveState: previousState.liveState,
23
+ publicState: previousState.publicState,
24
+ isLiveStateDirty: true,
25
+ lastUpdateTime: Date.now()
26
+ });
27
+ switch (action.type) {
28
+ case "publishNewestState": {
29
+ return publishNewState();
30
+ }
31
+ case "initialize": {
32
+ for (const [fileId, metadata] of action.files) {
33
+ previousState.liveState.set(fileId, {
34
+ readyState: "initializing",
35
+ abortController: metadata.abortController,
36
+ previewUrl: metadata.previewUrl,
37
+ file: metadata.file
38
+ });
39
+ previousState.fileIdByFile.set(metadata.file, fileId);
40
+ }
41
+ return publishNewState();
42
+ }
43
+ case "startUploading": {
44
+ for (const [fileOrId, metadata] of action.files) {
45
+ const fileId = toFileId(previousState, fileOrId);
46
+ const fileState = previousState.liveState.get(fileId);
47
+ if (fileState === void 0 || fileState.readyState !== "initializing") {
48
+ continue;
49
+ }
50
+ previousState.liveState.set(fileId, {
51
+ readyState: "uploading",
52
+ abortController: fileState.abortController,
53
+ file: fileState.file,
54
+ metadata: metadata.metadata,
55
+ previewUrl: fileState.previewUrl,
56
+ progress: void 0,
57
+ uploader: metadata.uploader
58
+ });
59
+ }
60
+ return publishNewState();
61
+ }
62
+ case "finishSuccessfully": {
63
+ for (const [fileOrId, result] of action.result) {
64
+ const fileId = toFileId(previousState, fileOrId);
65
+ const previousFileState = previousState.liveState.get(fileId);
66
+ if (previousFileState === void 0 || previousFileState.readyState !== "uploading") {
67
+ continue;
68
+ }
69
+ previousState.liveState.set(fileId, {
70
+ readyState: "success",
71
+ file: previousFileState.file,
72
+ metadata: previousFileState.metadata,
73
+ previewUrl: previousFileState.previewUrl,
74
+ result,
75
+ uploader: previousFileState.uploader
76
+ });
77
+ }
78
+ return getNewDirtyState();
79
+ }
80
+ case "finishWithError": {
81
+ for (const errorSpec of action.error) {
82
+ let fileOrId;
83
+ let rawError;
84
+ if (Array.isArray(errorSpec)) {
85
+ [fileOrId, rawError] = errorSpec;
86
+ } else {
87
+ fileOrId = errorSpec;
88
+ rawError = void 0;
89
+ }
90
+ const errors = [];
91
+ if (rawError instanceof FileUploadError) {
92
+ errors.push(rawError);
93
+ } else if (Array.isArray(rawError)) {
94
+ for (const error of rawError) {
95
+ if (error instanceof FileUploadError) {
96
+ errors.push(error);
97
+ }
98
+ }
99
+ }
100
+ const fileId = toFileId(previousState, fileOrId);
101
+ const previousFileState = previousState.liveState.get(fileId);
102
+ if (previousFileState === void 0 || previousFileState.readyState !== "initializing" && previousFileState.readyState !== "uploading") {
103
+ continue;
104
+ }
105
+ const uploader = previousFileState.readyState === "uploading" ? previousFileState.uploader : void 0;
106
+ const metadata = previousFileState.readyState === "uploading" ? previousFileState.metadata : void 0;
107
+ previousState.liveState.set(fileId, {
108
+ readyState: "error",
109
+ errors: errors.length ? errors : void 0,
110
+ rawError,
111
+ file: previousFileState.file,
112
+ metadata,
113
+ previewUrl: previousFileState.previewUrl,
114
+ uploader
115
+ });
116
+ }
117
+ return getNewDirtyState();
118
+ }
119
+ case "purge": {
120
+ let atLeastOnePurged = false;
121
+ for (const fileOrId of action.files) {
122
+ const fileId = toFileId(previousState, fileOrId);
123
+ const fileState = previousState.liveState.get(fileId);
124
+ if (fileState === void 0) {
125
+ continue;
126
+ }
127
+ atLeastOnePurged = true;
128
+ if (fileState.readyState === "initializing" || fileState.readyState === "uploading") {
129
+ fileState.abortController.abort();
130
+ }
131
+ previousState.liveState.delete(fileId);
132
+ }
133
+ if (atLeastOnePurged) {
134
+ return getNewDirtyState();
135
+ }
136
+ return previousState;
137
+ }
138
+ case "updateUploadProgress": {
139
+ for (const [fileOrId, { progress }] of action.progress) {
140
+ const fileId = toFileId(previousState, fileOrId);
141
+ const previousFileState = previousState.liveState.get(fileId);
142
+ if (progress === void 0 || previousFileState === void 0 || previousFileState.readyState !== "uploading") {
143
+ continue;
144
+ }
145
+ previousState.liveState.set(fileId, {
146
+ readyState: "uploading",
147
+ file: previousFileState.file,
148
+ uploader: previousFileState.uploader,
149
+ abortController: previousFileState.abortController,
150
+ previewUrl: previousFileState.previewUrl,
151
+ metadata: previousFileState.metadata,
152
+ progress
153
+ });
154
+ }
155
+ return getNewDirtyState();
156
+ }
157
+ }
158
+ assertNever();
159
+ };
160
+
161
+ export { fileUploadReducer, initializeFileUploadState };
162
+ //# sourceMappingURL=fileUploadReducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileUploadReducer.js","sources":["../../../src/upload/fileUploadReducer.ts"],"sourcesContent":["import { FileUploadError } from '@contember/client'\nimport { assertNever } from '../utils'\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<\n\tResult,\n\tMetadata\n> => ({\n\tlastUpdateTime: 0,\n\tfileIdByFile: new WeakMap<File, FileId>(),\n\tliveState: new Map(),\n\tpublicState: new Map(),\n\tisLiveStateDirty: false,\n})\n\nexport const fileUploadReducer = <Result = unknown, Metadata = undefined>(\n\tpreviousState: FileUploadMultiTemporalState<Result, Metadata>,\n\taction: FileUploadAction<Result, Metadata>,\n): FileUploadMultiTemporalState<Result, Metadata> => {\n\tconst publishNewState = (): FileUploadMultiTemporalState<Result, Metadata> => ({\n\t\tpublicState: previousState.liveState,\n\t\tfileIdByFile: previousState.fileIdByFile,\n\t\tlastUpdateTime: previousState.lastUpdateTime,\n\t\tisLiveStateDirty: false,\n\n\t\t// Immediately make the live state referentially unequal so that this doesn't have to happen during each action\n\t\t// several times between two publishes.\n\t\tliveState: new Map(previousState.liveState),\n\t})\n\tconst getNewDirtyState = (): FileUploadMultiTemporalState<Result, Metadata> => ({\n\t\tfileIdByFile: previousState.fileIdByFile,\n\t\tliveState: previousState.liveState,\n\t\tpublicState: previousState.publicState,\n\t\tisLiveStateDirty: true,\n\t\tlastUpdateTime: Date.now(),\n\t})\n\tswitch (action.type) {\n\t\tcase 'publishNewestState': {\n\t\t\treturn publishNewState()\n\t\t}\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\n\t\t\t\tpreviousState.liveState.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\tpreviousState.fileIdByFile.set(metadata.file, fileId)\n\t\t\t}\n\t\t\treturn publishNewState() /* Making the feedback about new files immediate*/\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 = previousState.liveState.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\tpreviousState.liveState.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\treturn publishNewState() /* Making the feedback about started upload immediate*/\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 = previousState.liveState.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\tpreviousState.liveState.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\t// return publishNewState() // Making the feedback about successful upload immediate.\n\t\t\treturn getNewDirtyState()\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 = previousState.liveState.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\tpreviousState.liveState.set(fileId, {\n\t\t\t\t\treadyState: 'error',\n\t\t\t\t\terrors: errors.length ? errors : undefined,\n\t\t\t\t\trawError,\n\t\t\t\t\tfile: previousFileState.file,\n\t\t\t\t\tmetadata,\n\t\t\t\t\tpreviewUrl: previousFileState.previewUrl,\n\t\t\t\t\tuploader,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn getNewDirtyState() // Bad news can wait.\n\t\t}\n\t\tcase 'purge': {\n\t\t\tlet atLeastOnePurged = false\n\t\t\tfor (const fileOrId of action.files) {\n\t\t\t\tconst fileId = toFileId(previousState, fileOrId)\n\t\t\t\tconst fileState = previousState.liveState.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\tatLeastOnePurged = true\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\tpreviousState.liveState.delete(fileId)\n\t\t\t}\n\t\t\tif (atLeastOnePurged) {\n\t\t\t\treturn getNewDirtyState()\n\t\t\t}\n\t\t\treturn previousState\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 = previousState.liveState.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\t\t\t\tpreviousState.liveState.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,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn getNewDirtyState()\n\t\t}\n\t}\n\tassertNever(action)\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ const toFileId = (state, fileOrId) => {
2
+ if (fileOrId instanceof File) {
3
+ return state.fileIdByFile.get(fileOrId);
4
+ }
5
+ return fileOrId;
6
+ };
7
+
8
+ export { toFileId };
9
+ //# sourceMappingURL=toFileId.js.map
@@ -0,0 +1 @@
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) => {\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":"MAGa,WAAW,CACvB,OACA,aACI;AACJ,MAAI,oBAAoB,MAAM;AAC7B,WAAO,MAAM,aAAa,IAAI;AAAA;AAE/B,SAAO;AAAA;;;;"}
@@ -0,0 +1,192 @@
1
+ import { S3FileUploader } from '@contember/client';
2
+ import { useRef, useReducer, useMemo, useEffect, useCallback } from 'react';
3
+ import { fileUploadReducer, initializeFileUploadState } from './fileUploadReducer.js';
4
+ import { toFileId } from './toFileId.js';
5
+ import { useCurrentContentGraphQlClient } from '../content/useCurrentContentGraphQlClient.js';
6
+
7
+ const useFileUpload = (options) => {
8
+ const maxUpdateFrequency = options?.maxUpdateFrequency ?? 100;
9
+ const contentApiClient = useCurrentContentGraphQlClient();
10
+ const updateTimeoutRef = useRef(void 0);
11
+ const isFirstRenderRef = useRef(true);
12
+ const fileIdSeedRef = useRef(1);
13
+ const [multiTemporalState, dispatch] = useReducer(fileUploadReducer, void 0, initializeFileUploadState);
14
+ const multiTemporalStateRef = useRef(multiTemporalState);
15
+ const defaultUploader = useMemo(() => new S3FileUploader(), []);
16
+ useEffect(() => {
17
+ multiTemporalStateRef.current = multiTemporalState;
18
+ });
19
+ const purgeUpload = useCallback((files) => {
20
+ dispatch({
21
+ type: "purge",
22
+ files
23
+ });
24
+ }, []);
25
+ const failUpload = useCallback((error) => {
26
+ dispatch({
27
+ type: "finishWithError",
28
+ error
29
+ });
30
+ }, []);
31
+ const initializeUpload = useCallback((files) => {
32
+ const newFileIds = new Set();
33
+ const fileWithMetadataByFileConfig = new Map();
34
+ for (const fileMaybeWithId of files) {
35
+ const abortController = new AbortController();
36
+ let fileId;
37
+ let file;
38
+ if (fileMaybeWithId instanceof File) {
39
+ fileId = `__contember__file-${fileIdSeedRef.current++}`;
40
+ file = fileMaybeWithId;
41
+ } else {
42
+ fileId = fileMaybeWithId[0];
43
+ file = fileMaybeWithId[1];
44
+ }
45
+ abortController.signal.addEventListener("abort", () => {
46
+ purgeUpload([fileId]);
47
+ });
48
+ fileWithMetadataByFileConfig.set(fileId, {
49
+ previewUrl: URL.createObjectURL(file),
50
+ abortController,
51
+ file,
52
+ fileId
53
+ });
54
+ newFileIds.add(fileId);
55
+ }
56
+ if (fileWithMetadataByFileConfig.size === 0) {
57
+ return fileWithMetadataByFileConfig;
58
+ }
59
+ if (newFileIds.size) {
60
+ dispatch({
61
+ type: "purge",
62
+ files: newFileIds
63
+ });
64
+ }
65
+ dispatch({
66
+ type: "initialize",
67
+ files: fileWithMetadataByFileConfig
68
+ });
69
+ return fileWithMetadataByFileConfig;
70
+ }, [purgeUpload]);
71
+ const startUpload = useCallback((files) => {
72
+ const filesById = new Map();
73
+ const groupedByUploader = new Map();
74
+ const currentState = multiTemporalStateRef.current;
75
+ for (const fileOrIdMaybeWithOptions of files) {
76
+ let fileOrId;
77
+ let options2;
78
+ if (Array.isArray(fileOrIdMaybeWithOptions)) {
79
+ fileOrId = fileOrIdMaybeWithOptions[0];
80
+ options2 = fileOrIdMaybeWithOptions[1];
81
+ } else {
82
+ fileOrId = fileOrIdMaybeWithOptions;
83
+ options2 = {};
84
+ }
85
+ const { uploader = defaultUploader, metadata } = options2;
86
+ const fileId = toFileId(currentState, fileOrId);
87
+ const fileState = currentState.liveState.get(fileId);
88
+ if (fileState === void 0 || fileState.readyState !== "initializing") {
89
+ throw new Error(`Trying to startUpload a file that hasn't been previously initialized. This will be possible in future, but isn't yet.`);
90
+ }
91
+ filesById.set(fileId, {
92
+ uploader,
93
+ metadata
94
+ });
95
+ let filesWithSameUploader = groupedByUploader.get(uploader);
96
+ if (filesWithSameUploader === void 0) {
97
+ groupedByUploader.set(uploader, filesWithSameUploader = new Map());
98
+ }
99
+ filesWithSameUploader.set(fileState.file, {
100
+ abortSignal: fileState.abortController.signal
101
+ });
102
+ }
103
+ dispatch({
104
+ type: "startUploading",
105
+ files: filesById
106
+ });
107
+ for (const [uploader, filesForUpload] of groupedByUploader) {
108
+ try {
109
+ uploader.upload(filesForUpload, {
110
+ onProgress: (progress) => {
111
+ dispatch({
112
+ type: "updateUploadProgress",
113
+ progress
114
+ });
115
+ },
116
+ onSuccess: (result) => {
117
+ dispatch({
118
+ type: "finishSuccessfully",
119
+ result
120
+ });
121
+ },
122
+ onError: (error) => {
123
+ dispatch({
124
+ type: "finishWithError",
125
+ error
126
+ });
127
+ },
128
+ contentApiClient
129
+ });
130
+ } catch (error) {
131
+ dispatch({
132
+ type: "finishWithError",
133
+ error: Array.from(filesForUpload).map(([file]) => [file, error])
134
+ });
135
+ }
136
+ }
137
+ }, [contentApiClient, defaultUploader]);
138
+ const operations = useMemo(() => ({
139
+ failUpload,
140
+ initializeUpload,
141
+ purgeUpload,
142
+ startUpload
143
+ }), [failUpload, initializeUpload, purgeUpload, startUpload]);
144
+ useEffect(() => {
145
+ if (isFirstRenderRef.current) {
146
+ return;
147
+ }
148
+ if (multiTemporalState.isLiveStateDirty) {
149
+ const now = Date.now();
150
+ const timeDelta = Math.max(now - multiTemporalState.lastUpdateTime, 0);
151
+ if (timeDelta > maxUpdateFrequency) {
152
+ if (updateTimeoutRef.current !== void 0) {
153
+ clearTimeout(updateTimeoutRef.current);
154
+ }
155
+ dispatch({
156
+ type: "publishNewestState"
157
+ });
158
+ } else {
159
+ if (updateTimeoutRef.current !== void 0) {
160
+ return;
161
+ }
162
+ updateTimeoutRef.current = window.setTimeout(() => {
163
+ dispatch({
164
+ type: "publishNewestState"
165
+ });
166
+ updateTimeoutRef.current = void 0;
167
+ }, maxUpdateFrequency - timeDelta);
168
+ }
169
+ }
170
+ }, [
171
+ multiTemporalState.isLiveStateDirty,
172
+ multiTemporalState.lastUpdateTime,
173
+ multiTemporalState.liveState,
174
+ multiTemporalState.publicState,
175
+ maxUpdateFrequency
176
+ ]);
177
+ useEffect(() => () => {
178
+ for (const [, state] of multiTemporalStateRef.current.liveState) {
179
+ URL.revokeObjectURL(state.previewUrl);
180
+ }
181
+ for (const [, state] of multiTemporalStateRef.current.publicState) {
182
+ URL.revokeObjectURL(state.previewUrl);
183
+ }
184
+ }, []);
185
+ useEffect(() => {
186
+ isFirstRenderRef.current = false;
187
+ }, []);
188
+ return [multiTemporalState.publicState, operations];
189
+ };
190
+
191
+ export { useFileUpload };
192
+ //# sourceMappingURL=useFileUpload.js.map