@streetjs/storage 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +719 -0
- package/dist/access.d.ts +95 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +114 -0
- package/dist/access.js.map +1 -0
- package/dist/cli/commands.d.ts +88 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +369 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/generators.d.ts +41 -0
- package/dist/cli/generators.d.ts.map +1 -0
- package/dist/cli/generators.js +119 -0
- package/dist/cli/generators.js.map +1 -0
- package/dist/directory.d.ts +88 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +148 -0
- package/dist/directory.js.map +1 -0
- package/dist/driver.d.ts +83 -0
- package/dist/driver.d.ts.map +1 -0
- package/dist/driver.js +16 -0
- package/dist/driver.js.map +1 -0
- package/dist/drivers/azure.d.ts +239 -0
- package/dist/drivers/azure.d.ts.map +1 -0
- package/dist/drivers/azure.js +476 -0
- package/dist/drivers/azure.js.map +1 -0
- package/dist/drivers/backblaze.d.ts +105 -0
- package/dist/drivers/backblaze.d.ts.map +1 -0
- package/dist/drivers/backblaze.js +279 -0
- package/dist/drivers/backblaze.js.map +1 -0
- package/dist/drivers/gcs.d.ts +239 -0
- package/dist/drivers/gcs.d.ts.map +1 -0
- package/dist/drivers/gcs.js +454 -0
- package/dist/drivers/gcs.js.map +1 -0
- package/dist/drivers/local.d.ts +126 -0
- package/dist/drivers/local.d.ts.map +1 -0
- package/dist/drivers/local.js +321 -0
- package/dist/drivers/local.js.map +1 -0
- package/dist/drivers/memory.d.ts +104 -0
- package/dist/drivers/memory.d.ts.map +1 -0
- package/dist/drivers/memory.js +197 -0
- package/dist/drivers/memory.js.map +1 -0
- package/dist/drivers/minio.d.ts +90 -0
- package/dist/drivers/minio.d.ts.map +1 -0
- package/dist/drivers/minio.js +276 -0
- package/dist/drivers/minio.js.map +1 -0
- package/dist/drivers/r2.d.ts +100 -0
- package/dist/drivers/r2.d.ts.map +1 -0
- package/dist/drivers/r2.js +240 -0
- package/dist/drivers/r2.js.map +1 -0
- package/dist/drivers/s3-base.d.ts +270 -0
- package/dist/drivers/s3-base.d.ts.map +1 -0
- package/dist/drivers/s3-base.js +436 -0
- package/dist/drivers/s3-base.js.map +1 -0
- package/dist/drivers/s3.d.ts +111 -0
- package/dist/drivers/s3.d.ts.map +1 -0
- package/dist/drivers/s3.js +311 -0
- package/dist/drivers/s3.js.map +1 -0
- package/dist/drivers/supabase.d.ts +246 -0
- package/dist/drivers/supabase.d.ts.map +1 -0
- package/dist/drivers/supabase.js +502 -0
- package/dist/drivers/supabase.js.map +1 -0
- package/dist/errors.d.ts +115 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +131 -0
- package/dist/errors.js.map +1 -0
- package/dist/examples/storage-demo.d.ts +53 -0
- package/dist/examples/storage-demo.d.ts.map +1 -0
- package/dist/examples/storage-demo.js +242 -0
- package/dist/examples/storage-demo.js.map +1 -0
- package/dist/facade.d.ts +192 -0
- package/dist/facade.d.ts.map +1 -0
- package/dist/facade.js +898 -0
- package/dist/facade.js.map +1 -0
- package/dist/image.d.ts +94 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +224 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/events.d.ts +108 -0
- package/dist/integrations/events.d.ts.map +1 -0
- package/dist/integrations/events.js +111 -0
- package/dist/integrations/events.js.map +1 -0
- package/dist/integrations/queue.d.ts +89 -0
- package/dist/integrations/queue.d.ts.map +1 -0
- package/dist/integrations/queue.js +91 -0
- package/dist/integrations/queue.js.map +1 -0
- package/dist/integrations/realtime.d.ts +95 -0
- package/dist/integrations/realtime.d.ts.map +1 -0
- package/dist/integrations/realtime.js +90 -0
- package/dist/integrations/realtime.js.map +1 -0
- package/dist/lifecycle.d.ts +137 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +240 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/metadata.d.ts +109 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +139 -0
- package/dist/metadata.js.map +1 -0
- package/dist/multipart.d.ts +108 -0
- package/dist/multipart.d.ts.map +1 -0
- package/dist/multipart.js +200 -0
- package/dist/multipart.js.map +1 -0
- package/dist/observability.d.ts +82 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +175 -0
- package/dist/observability.js.map +1 -0
- package/dist/plugin.d.ts +82 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +100 -0
- package/dist/plugin.js.map +1 -0
- package/dist/resumable.d.ts +118 -0
- package/dist/resumable.d.ts.map +1 -0
- package/dist/resumable.js +223 -0
- package/dist/resumable.js.map +1 -0
- package/dist/search.d.ts +57 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +172 -0
- package/dist/search.js.map +1 -0
- package/dist/signed-url.d.ts +110 -0
- package/dist/signed-url.d.ts.map +1 -0
- package/dist/signed-url.js +237 -0
- package/dist/signed-url.js.map +1 -0
- package/dist/testing/index.d.ts +219 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +393 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tests/access.test.d.ts +2 -0
- package/dist/tests/access.test.d.ts.map +1 -0
- package/dist/tests/access.test.js +270 -0
- package/dist/tests/access.test.js.map +1 -0
- package/dist/tests/azure-driver.test.d.ts +2 -0
- package/dist/tests/azure-driver.test.d.ts.map +1 -0
- package/dist/tests/azure-driver.test.js +183 -0
- package/dist/tests/azure-driver.test.js.map +1 -0
- package/dist/tests/backblaze-driver.test.d.ts +2 -0
- package/dist/tests/backblaze-driver.test.d.ts.map +1 -0
- package/dist/tests/backblaze-driver.test.js +185 -0
- package/dist/tests/backblaze-driver.test.js.map +1 -0
- package/dist/tests/bridge-degradation.test.d.ts +2 -0
- package/dist/tests/bridge-degradation.test.d.ts.map +1 -0
- package/dist/tests/bridge-degradation.test.js +138 -0
- package/dist/tests/bridge-degradation.test.js.map +1 -0
- package/dist/tests/cli.test.d.ts +2 -0
- package/dist/tests/cli.test.d.ts.map +1 -0
- package/dist/tests/cli.test.js +127 -0
- package/dist/tests/cli.test.js.map +1 -0
- package/dist/tests/contract.d.ts +131 -0
- package/dist/tests/contract.d.ts.map +1 -0
- package/dist/tests/contract.js +222 -0
- package/dist/tests/contract.js.map +1 -0
- package/dist/tests/contract.test.d.ts +2 -0
- package/dist/tests/contract.test.d.ts.map +1 -0
- package/dist/tests/contract.test.js +110 -0
- package/dist/tests/contract.test.js.map +1 -0
- package/dist/tests/directory.test.d.ts +2 -0
- package/dist/tests/directory.test.d.ts.map +1 -0
- package/dist/tests/directory.test.js +125 -0
- package/dist/tests/directory.test.js.map +1 -0
- package/dist/tests/errors.test.d.ts +2 -0
- package/dist/tests/errors.test.d.ts.map +1 -0
- package/dist/tests/errors.test.js +93 -0
- package/dist/tests/errors.test.js.map +1 -0
- package/dist/tests/events-bridge.test.d.ts +2 -0
- package/dist/tests/events-bridge.test.d.ts.map +1 -0
- package/dist/tests/events-bridge.test.js +228 -0
- package/dist/tests/events-bridge.test.js.map +1 -0
- package/dist/tests/example-smoke.test.d.ts +2 -0
- package/dist/tests/example-smoke.test.d.ts.map +1 -0
- package/dist/tests/example-smoke.test.js +34 -0
- package/dist/tests/example-smoke.test.js.map +1 -0
- package/dist/tests/gcs-driver.test.d.ts +2 -0
- package/dist/tests/gcs-driver.test.d.ts.map +1 -0
- package/dist/tests/gcs-driver.test.js +197 -0
- package/dist/tests/gcs-driver.test.js.map +1 -0
- package/dist/tests/image.test.d.ts +2 -0
- package/dist/tests/image.test.d.ts.map +1 -0
- package/dist/tests/image.test.js +102 -0
- package/dist/tests/image.test.js.map +1 -0
- package/dist/tests/lifecycle.test.d.ts +2 -0
- package/dist/tests/lifecycle.test.d.ts.map +1 -0
- package/dist/tests/lifecycle.test.js +171 -0
- package/dist/tests/lifecycle.test.js.map +1 -0
- package/dist/tests/local-driver.test.d.ts +2 -0
- package/dist/tests/local-driver.test.d.ts.map +1 -0
- package/dist/tests/local-driver.test.js +153 -0
- package/dist/tests/local-driver.test.js.map +1 -0
- package/dist/tests/local-streaming.test.d.ts +2 -0
- package/dist/tests/local-streaming.test.d.ts.map +1 -0
- package/dist/tests/local-streaming.test.js +121 -0
- package/dist/tests/local-streaming.test.js.map +1 -0
- package/dist/tests/memory-driver.test.d.ts +2 -0
- package/dist/tests/memory-driver.test.d.ts.map +1 -0
- package/dist/tests/memory-driver.test.js +180 -0
- package/dist/tests/memory-driver.test.js.map +1 -0
- package/dist/tests/memory-streaming.test.d.ts +2 -0
- package/dist/tests/memory-streaming.test.d.ts.map +1 -0
- package/dist/tests/memory-streaming.test.js +92 -0
- package/dist/tests/memory-streaming.test.js.map +1 -0
- package/dist/tests/minio-driver.test.d.ts +2 -0
- package/dist/tests/minio-driver.test.d.ts.map +1 -0
- package/dist/tests/minio-driver.test.js +146 -0
- package/dist/tests/minio-driver.test.js.map +1 -0
- package/dist/tests/non-s3-integration.test.d.ts +2 -0
- package/dist/tests/non-s3-integration.test.d.ts.map +1 -0
- package/dist/tests/non-s3-integration.test.js +201 -0
- package/dist/tests/non-s3-integration.test.js.map +1 -0
- package/dist/tests/observability.registration.test.d.ts +2 -0
- package/dist/tests/observability.registration.test.d.ts.map +1 -0
- package/dist/tests/observability.registration.test.js +103 -0
- package/dist/tests/observability.registration.test.js.map +1 -0
- package/dist/tests/observability.test.d.ts +2 -0
- package/dist/tests/observability.test.d.ts.map +1 -0
- package/dist/tests/observability.test.js +240 -0
- package/dist/tests/observability.test.js.map +1 -0
- package/dist/tests/plugin.test.d.ts +2 -0
- package/dist/tests/plugin.test.d.ts.map +1 -0
- package/dist/tests/plugin.test.js +112 -0
- package/dist/tests/plugin.test.js.map +1 -0
- package/dist/tests/prop-concurrent.test.d.ts +2 -0
- package/dist/tests/prop-concurrent.test.d.ts.map +1 -0
- package/dist/tests/prop-concurrent.test.js +59 -0
- package/dist/tests/prop-concurrent.test.js.map +1 -0
- package/dist/tests/prop-copy.test.d.ts +2 -0
- package/dist/tests/prop-copy.test.d.ts.map +1 -0
- package/dist/tests/prop-copy.test.js +63 -0
- package/dist/tests/prop-copy.test.js.map +1 -0
- package/dist/tests/prop-delete.test.d.ts +2 -0
- package/dist/tests/prop-delete.test.d.ts.map +1 -0
- package/dist/tests/prop-delete.test.js +35 -0
- package/dist/tests/prop-delete.test.js.map +1 -0
- package/dist/tests/prop-directory.test.d.ts +2 -0
- package/dist/tests/prop-directory.test.d.ts.map +1 -0
- package/dist/tests/prop-directory.test.js +118 -0
- package/dist/tests/prop-directory.test.js.map +1 -0
- package/dist/tests/prop-driver-conformance.test.d.ts +2 -0
- package/dist/tests/prop-driver-conformance.test.d.ts.map +1 -0
- package/dist/tests/prop-driver-conformance.test.js +110 -0
- package/dist/tests/prop-driver-conformance.test.js.map +1 -0
- package/dist/tests/prop-driver-equivalence.test.d.ts +2 -0
- package/dist/tests/prop-driver-equivalence.test.d.ts.map +1 -0
- package/dist/tests/prop-driver-equivalence.test.js +163 -0
- package/dist/tests/prop-driver-equivalence.test.js.map +1 -0
- package/dist/tests/prop-lifecycle.test.d.ts +2 -0
- package/dist/tests/prop-lifecycle.test.d.ts.map +1 -0
- package/dist/tests/prop-lifecycle.test.js +83 -0
- package/dist/tests/prop-lifecycle.test.js.map +1 -0
- package/dist/tests/prop-list.test.d.ts +2 -0
- package/dist/tests/prop-list.test.d.ts.map +1 -0
- package/dist/tests/prop-list.test.js +53 -0
- package/dist/tests/prop-list.test.js.map +1 -0
- package/dist/tests/prop-metadata.test.d.ts +2 -0
- package/dist/tests/prop-metadata.test.d.ts.map +1 -0
- package/dist/tests/prop-metadata.test.js +87 -0
- package/dist/tests/prop-metadata.test.js.map +1 -0
- package/dist/tests/prop-move.test.d.ts +2 -0
- package/dist/tests/prop-move.test.d.ts.map +1 -0
- package/dist/tests/prop-move.test.js +67 -0
- package/dist/tests/prop-move.test.js.map +1 -0
- package/dist/tests/prop-multipart-abort.test.d.ts +2 -0
- package/dist/tests/prop-multipart-abort.test.d.ts.map +1 -0
- package/dist/tests/prop-multipart-abort.test.js +48 -0
- package/dist/tests/prop-multipart-abort.test.js.map +1 -0
- package/dist/tests/prop-multipart.test.d.ts +2 -0
- package/dist/tests/prop-multipart.test.d.ts.map +1 -0
- package/dist/tests/prop-multipart.test.js +65 -0
- package/dist/tests/prop-multipart.test.js.map +1 -0
- package/dist/tests/prop-resumable.test.d.ts +2 -0
- package/dist/tests/prop-resumable.test.d.ts.map +1 -0
- package/dist/tests/prop-resumable.test.js +78 -0
- package/dist/tests/prop-resumable.test.js.map +1 -0
- package/dist/tests/prop-search.test.d.ts +2 -0
- package/dist/tests/prop-search.test.d.ts.map +1 -0
- package/dist/tests/prop-search.test.js +120 -0
- package/dist/tests/prop-search.test.js.map +1 -0
- package/dist/tests/prop-signed-url.test.d.ts +2 -0
- package/dist/tests/prop-signed-url.test.d.ts.map +1 -0
- package/dist/tests/prop-signed-url.test.js +74 -0
- package/dist/tests/prop-signed-url.test.js.map +1 -0
- package/dist/tests/prop-streaming.test.d.ts +2 -0
- package/dist/tests/prop-streaming.test.d.ts.map +1 -0
- package/dist/tests/prop-streaming.test.js +34 -0
- package/dist/tests/prop-streaming.test.js.map +1 -0
- package/dist/tests/prop-upload-download.test.d.ts +2 -0
- package/dist/tests/prop-upload-download.test.d.ts.map +1 -0
- package/dist/tests/prop-upload-download.test.js +30 -0
- package/dist/tests/prop-upload-download.test.js.map +1 -0
- package/dist/tests/prop-validation.test.d.ts +2 -0
- package/dist/tests/prop-validation.test.d.ts.map +1 -0
- package/dist/tests/prop-validation.test.js +50 -0
- package/dist/tests/prop-validation.test.js.map +1 -0
- package/dist/tests/prop-versioning.test.d.ts +2 -0
- package/dist/tests/prop-versioning.test.d.ts.map +1 -0
- package/dist/tests/prop-versioning.test.js +74 -0
- package/dist/tests/prop-versioning.test.js.map +1 -0
- package/dist/tests/queue-bridge.test.d.ts +2 -0
- package/dist/tests/queue-bridge.test.d.ts.map +1 -0
- package/dist/tests/queue-bridge.test.js +111 -0
- package/dist/tests/queue-bridge.test.js.map +1 -0
- package/dist/tests/r2-driver.test.d.ts +2 -0
- package/dist/tests/r2-driver.test.d.ts.map +1 -0
- package/dist/tests/r2-driver.test.js +143 -0
- package/dist/tests/r2-driver.test.js.map +1 -0
- package/dist/tests/realtime-bridge.test.d.ts +2 -0
- package/dist/tests/realtime-bridge.test.d.ts.map +1 -0
- package/dist/tests/realtime-bridge.test.js +106 -0
- package/dist/tests/realtime-bridge.test.js.map +1 -0
- package/dist/tests/resumable.test.d.ts +2 -0
- package/dist/tests/resumable.test.d.ts.map +1 -0
- package/dist/tests/resumable.test.js +104 -0
- package/dist/tests/resumable.test.js.map +1 -0
- package/dist/tests/s3-base.test.d.ts +2 -0
- package/dist/tests/s3-base.test.d.ts.map +1 -0
- package/dist/tests/s3-base.test.js +289 -0
- package/dist/tests/s3-base.test.js.map +1 -0
- package/dist/tests/s3-integration.test.d.ts +2 -0
- package/dist/tests/s3-integration.test.d.ts.map +1 -0
- package/dist/tests/s3-integration.test.js +270 -0
- package/dist/tests/s3-integration.test.js.map +1 -0
- package/dist/tests/s3.test.d.ts +2 -0
- package/dist/tests/s3.test.d.ts.map +1 -0
- package/dist/tests/s3.test.js +203 -0
- package/dist/tests/s3.test.js.map +1 -0
- package/dist/tests/scaffold.test.d.ts +2 -0
- package/dist/tests/scaffold.test.d.ts.map +1 -0
- package/dist/tests/scaffold.test.js +13 -0
- package/dist/tests/scaffold.test.js.map +1 -0
- package/dist/tests/search.test.d.ts +2 -0
- package/dist/tests/search.test.d.ts.map +1 -0
- package/dist/tests/search.test.js +106 -0
- package/dist/tests/search.test.js.map +1 -0
- package/dist/tests/supabase-driver.test.d.ts +2 -0
- package/dist/tests/supabase-driver.test.d.ts.map +1 -0
- package/dist/tests/supabase-driver.test.js +196 -0
- package/dist/tests/supabase-driver.test.js.map +1 -0
- package/dist/tests/testing-utilities.test.d.ts +2 -0
- package/dist/tests/testing-utilities.test.d.ts.map +1 -0
- package/dist/tests/testing-utilities.test.js +138 -0
- package/dist/tests/testing-utilities.test.js.map +1 -0
- package/dist/tests/validation.test.d.ts +2 -0
- package/dist/tests/validation.test.d.ts.map +1 -0
- package/dist/tests/validation.test.js +135 -0
- package/dist/tests/validation.test.js.map +1 -0
- package/dist/tests/versioning.test.d.ts +2 -0
- package/dist/tests/versioning.test.d.ts.map +1 -0
- package/dist/tests/versioning.test.js +128 -0
- package/dist/tests/versioning.test.js.map +1 -0
- package/dist/types.d.ts +232 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +105 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +225 -0
- package/dist/validation.js.map +1 -0
- package/dist/versioning.d.ts +100 -0
- package/dist/versioning.d.ts.map +1 -0
- package/dist/versioning.js +179 -0
- package/dist/versioning.js.map +1 -0
- package/package.json +137 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Events integration bridge.
|
|
3
|
+
*
|
|
4
|
+
* This module publishes typed storage lifecycle events (`storage.uploaded`,
|
|
5
|
+
* `storage.deleted`, `storage.updated`, `storage.moved`, `storage.restored`,
|
|
6
|
+
* `storage.expired`) through an events layer, each payload carrying the affected
|
|
7
|
+
* object key and (when available) its {@link StorageObjectMetadata}
|
|
8
|
+
* (Requirements 18.1, 18.2). Lifecycle-rule actions publish through this same
|
|
9
|
+
* bridge (Requirement 13.4).
|
|
10
|
+
*
|
|
11
|
+
* Following the events package's structural-interface pattern, the bridge
|
|
12
|
+
* depends only on the minimal {@link EventsLike} shape declared in `types.ts`
|
|
13
|
+
* (any object exposing `publish(event, payload)`), never on the concrete
|
|
14
|
+
* `@streetjs/events` package, so there is no hard dependency and no circular
|
|
15
|
+
* dependency (Requirements 18.3, 28.3). {@link EventsLike} is re-exported here
|
|
16
|
+
* for convenience; it is intentionally the single definition that lives in
|
|
17
|
+
* `types.ts`.
|
|
18
|
+
*
|
|
19
|
+
* **Never throws into the operation path.** Every publish is wrapped so that a
|
|
20
|
+
* synchronous throw or an asynchronous rejection from the underlying events
|
|
21
|
+
* layer is swallowed: a publish failure must never break the storage operation
|
|
22
|
+
* that triggered it. This mirrors the graceful-degradation guarantee the Queue
|
|
23
|
+
* and Realtime bridges also uphold.
|
|
24
|
+
*
|
|
25
|
+
* The facade constructs a {@link StorageEventPublisher} via
|
|
26
|
+
* {@link bridgeStorageEvents} only when `config.bridges?.events` is provided;
|
|
27
|
+
* when it is absent the facade holds no publisher and event publication is a
|
|
28
|
+
* complete no-op.
|
|
29
|
+
*
|
|
30
|
+
* _Requirements: 13.4, 18.1, 18.2, 18.3, 28.3_
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Map an applied {@link LifecycleOutcome} action onto its typed storage event
|
|
34
|
+
* name. `archived` is surfaced as `storage.moved` because archiving relocates
|
|
35
|
+
* the object under the reserved archive prefix; the original action is retained
|
|
36
|
+
* in the payload so listeners can still tell the two apart.
|
|
37
|
+
*/
|
|
38
|
+
const LIFECYCLE_EVENT_BY_ACTION = {
|
|
39
|
+
deleted: "storage.deleted",
|
|
40
|
+
expired: "storage.expired",
|
|
41
|
+
moved: "storage.moved",
|
|
42
|
+
archived: "storage.moved",
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Isolate a single publish call. A synchronous throw is caught; a returned
|
|
46
|
+
* promise has its rejection swallowed. Either way nothing propagates back to the
|
|
47
|
+
* storage operation that triggered the event, satisfying the "never throw into
|
|
48
|
+
* the operation path" guarantee.
|
|
49
|
+
*/
|
|
50
|
+
function safePublish(events, event, payload) {
|
|
51
|
+
try {
|
|
52
|
+
const result = events.publish(event, payload);
|
|
53
|
+
if (result !== undefined && result !== null && typeof result.then === "function") {
|
|
54
|
+
// Fire-and-forget: absorb any asynchronous rejection.
|
|
55
|
+
result.then(undefined, () => {
|
|
56
|
+
/* swallow — a publish failure must not break the storage op */
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// swallow — a publish failure must not break the storage op
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a {@link StorageEventPublisher} that publishes typed storage events
|
|
66
|
+
* through the supplied structural {@link EventsLike} bridge.
|
|
67
|
+
*
|
|
68
|
+
* The returned publisher is what the facade wires into its object operations
|
|
69
|
+
* (`put` → uploaded/updated, `delete` → deleted, `move`/`rename` → moved,
|
|
70
|
+
* `restoreVersion` → restored) and its lifecycle evaluation (`applyLifecycle`
|
|
71
|
+
* → deleted/expired/moved via {@link StorageEventPublisher.lifecycle}). Every
|
|
72
|
+
* method is guaranteed never to throw into the caller.
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* const publisher = bridgeStorageEvents(events);
|
|
76
|
+
* publisher.uploaded(metadata); // publishes "storage.uploaded" — never throws
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function bridgeStorageEvents(events) {
|
|
80
|
+
const publish = (event, payload) => {
|
|
81
|
+
safePublish(events, event, payload);
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
publish,
|
|
85
|
+
uploaded(metadata) {
|
|
86
|
+
publish("storage.uploaded", { key: metadata.key, metadata });
|
|
87
|
+
},
|
|
88
|
+
updated(metadata) {
|
|
89
|
+
publish("storage.updated", { key: metadata.key, metadata });
|
|
90
|
+
},
|
|
91
|
+
deleted(key, metadata) {
|
|
92
|
+
publish("storage.deleted", { key, metadata });
|
|
93
|
+
},
|
|
94
|
+
moved(metadata) {
|
|
95
|
+
publish("storage.moved", { key: metadata.key, metadata });
|
|
96
|
+
},
|
|
97
|
+
restored(metadata) {
|
|
98
|
+
publish("storage.restored", { key: metadata.key, metadata });
|
|
99
|
+
},
|
|
100
|
+
expired(key, metadata) {
|
|
101
|
+
publish("storage.expired", { key, metadata });
|
|
102
|
+
},
|
|
103
|
+
lifecycle(outcome) {
|
|
104
|
+
publish(LIFECYCLE_EVENT_BY_ACTION[outcome.action], {
|
|
105
|
+
key: outcome.key,
|
|
106
|
+
action: outcome.action,
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/integrations/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAmFH;;;;;GAKG;AACH,MAAM,yBAAyB,GAAmE;IAChG,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,iBAAiB;IAC1B,KAAK,EAAE,eAAe;IACtB,QAAQ,EAAE,eAAe;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,SAAS,WAAW,CAAC,MAAkB,EAAE,KAAuB,EAAE,OAA4B;IAC5F,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAQ,MAAwB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACpG,sDAAsD;YACrD,MAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC7C,+DAA+D;YACjE,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4DAA4D;IAC9D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,MAAM,OAAO,GAAG,CAAC,KAAuB,EAAE,OAA4B,EAAQ,EAAE;QAC9E,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,OAAO;QACL,OAAO;QACP,QAAQ,CAAC,QAAQ;YACf,OAAO,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,QAAQ;YACd,OAAO,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,QAAQ;YACnB,OAAO,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,KAAK,CAAC,QAAQ;YACZ,OAAO,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,QAAQ,CAAC,QAAQ;YACf,OAAO,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,QAAQ;YACnB,OAAO,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,SAAS,CAAC,OAAO;YACf,OAAO,CAAC,yBAAyB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACjD,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Queue integration bridge.
|
|
3
|
+
*
|
|
4
|
+
* This module hands heavy, out-of-band work off to a background queue so that
|
|
5
|
+
* storage operations never block on it: thumbnail generation, virus scanning,
|
|
6
|
+
* OCR, PDF processing, transcoding, image optimization, and archive creation
|
|
7
|
+
* (Requirement 17.1). Each job is dispatched through the minimal
|
|
8
|
+
* {@link QueueLike} shape declared in `types.ts` (any object exposing
|
|
9
|
+
* `dispatch(job, payload)`), never through the concrete `@streetjs/queue`
|
|
10
|
+
* package, so there is no hard dependency and no circular dependency
|
|
11
|
+
* (Requirements 17.2, 28.3). {@link QueueLike} is re-exported here for
|
|
12
|
+
* convenience; it is intentionally the single definition that lives in
|
|
13
|
+
* `types.ts`.
|
|
14
|
+
*
|
|
15
|
+
* **Never throws into the operation path.** Every dispatch is wrapped so that a
|
|
16
|
+
* synchronous throw or an asynchronous rejection from the underlying queue is
|
|
17
|
+
* swallowed: a dispatch failure must never break the storage operation that
|
|
18
|
+
* triggered it (Requirement 17.4). Equally, when no queue bridge is configured
|
|
19
|
+
* the facade holds no publisher and job dispatch is a complete no-op — storage
|
|
20
|
+
* operations proceed unaffected (Requirement 17.3). This mirrors the
|
|
21
|
+
* graceful-degradation guarantee the Events and Realtime bridges also uphold.
|
|
22
|
+
*
|
|
23
|
+
* The facade constructs a {@link StorageQueuePublisher} via
|
|
24
|
+
* {@link bridgeStorageQueue} only when `config.bridges?.queue` is provided.
|
|
25
|
+
*
|
|
26
|
+
* _Requirements: 17.1, 17.2, 17.3, 17.4, 28.3_
|
|
27
|
+
*/
|
|
28
|
+
import type { QueueLike } from "../types.js";
|
|
29
|
+
export type { QueueLike } from "../types.js";
|
|
30
|
+
/**
|
|
31
|
+
* The exhaustive set of background job names the storage framework dispatches
|
|
32
|
+
* (Requirement 17.1). Every heavy, out-of-band task maps onto exactly one of
|
|
33
|
+
* these names.
|
|
34
|
+
*/
|
|
35
|
+
export type StorageJobName = "storage.thumbnail" | "storage.virus-scan" | "storage.ocr" | "storage.pdf-process" | "storage.transcode" | "storage.image-optimize" | "storage.archive";
|
|
36
|
+
/**
|
|
37
|
+
* The payload dispatched with every storage job. It always carries the affected
|
|
38
|
+
* object `key` and, when the triggering operation has it in hand, arbitrary
|
|
39
|
+
* job-specific `options` the worker uses to perform the task.
|
|
40
|
+
*/
|
|
41
|
+
export interface StorageJobPayload {
|
|
42
|
+
/** The affected object key (always present). */
|
|
43
|
+
readonly key: string;
|
|
44
|
+
/** Job-specific options passed through to the worker (optional). */
|
|
45
|
+
readonly options?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The publisher the facade holds and can call to hand heavy work to the queue.
|
|
49
|
+
* Every method is fire-and-forget and guaranteed never to throw into the
|
|
50
|
+
* caller: the underlying dispatch is isolated so a failing (or absent) queue
|
|
51
|
+
* cannot break a storage operation (Requirements 17.3, 17.4).
|
|
52
|
+
*/
|
|
53
|
+
export interface StorageQueuePublisher {
|
|
54
|
+
/**
|
|
55
|
+
* Dispatch an already-named background job with the given payload. Never
|
|
56
|
+
* throws. The typed convenience methods below are thin wrappers over this.
|
|
57
|
+
*/
|
|
58
|
+
dispatch(job: StorageJobName, payload: StorageJobPayload): void;
|
|
59
|
+
/** Dispatch a thumbnail-generation job for an object. */
|
|
60
|
+
thumbnail(key: string, options?: Record<string, unknown>): void;
|
|
61
|
+
/** Dispatch a virus-scan job for an object. */
|
|
62
|
+
virusScan(key: string, options?: Record<string, unknown>): void;
|
|
63
|
+
/** Dispatch an OCR (text-extraction) job for an object. */
|
|
64
|
+
ocr(key: string, options?: Record<string, unknown>): void;
|
|
65
|
+
/** Dispatch a PDF-processing job for an object. */
|
|
66
|
+
pdfProcess(key: string, options?: Record<string, unknown>): void;
|
|
67
|
+
/** Dispatch a media-transcoding job for an object. */
|
|
68
|
+
transcode(key: string, options?: Record<string, unknown>): void;
|
|
69
|
+
/** Dispatch an image-optimization job for an object. */
|
|
70
|
+
imageOptimize(key: string, options?: Record<string, unknown>): void;
|
|
71
|
+
/** Dispatch an archive-creation job for an object. */
|
|
72
|
+
archive(key: string, options?: Record<string, unknown>): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a {@link StorageQueuePublisher} that dispatches background jobs through
|
|
76
|
+
* the supplied structural {@link QueueLike} bridge.
|
|
77
|
+
*
|
|
78
|
+
* The returned publisher is what the facade wires into any heavy, out-of-band
|
|
79
|
+
* work (thumbnail generation, virus scanning, OCR, PDF processing, transcoding,
|
|
80
|
+
* image optimization, archive creation). Every method is guaranteed never to
|
|
81
|
+
* throw into the caller.
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* const publisher = bridgeStorageQueue(queue);
|
|
85
|
+
* publisher.thumbnail("photo.png"); // dispatches "storage.thumbnail" — never throws
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function bridgeStorageQueue(queue: QueueLike): StorageQueuePublisher;
|
|
89
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/integrations/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB,mBAAmB,GACnB,oBAAoB,GACpB,aAAa,GACb,qBAAqB,GACrB,mBAAmB,GACnB,wBAAwB,GACxB,iBAAiB,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEhE,yDAAyD;IACzD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEhE,+CAA+C;IAC/C,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEhE,2DAA2D;IAC3D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAE1D,mDAAmD;IACnD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEjE,sDAAsD;IACtD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEhE,wDAAwD;IACxD,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAEpE,sDAAsD;IACtD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC/D;AAsBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,qBAAqB,CA6B1E"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Queue integration bridge.
|
|
3
|
+
*
|
|
4
|
+
* This module hands heavy, out-of-band work off to a background queue so that
|
|
5
|
+
* storage operations never block on it: thumbnail generation, virus scanning,
|
|
6
|
+
* OCR, PDF processing, transcoding, image optimization, and archive creation
|
|
7
|
+
* (Requirement 17.1). Each job is dispatched through the minimal
|
|
8
|
+
* {@link QueueLike} shape declared in `types.ts` (any object exposing
|
|
9
|
+
* `dispatch(job, payload)`), never through the concrete `@streetjs/queue`
|
|
10
|
+
* package, so there is no hard dependency and no circular dependency
|
|
11
|
+
* (Requirements 17.2, 28.3). {@link QueueLike} is re-exported here for
|
|
12
|
+
* convenience; it is intentionally the single definition that lives in
|
|
13
|
+
* `types.ts`.
|
|
14
|
+
*
|
|
15
|
+
* **Never throws into the operation path.** Every dispatch is wrapped so that a
|
|
16
|
+
* synchronous throw or an asynchronous rejection from the underlying queue is
|
|
17
|
+
* swallowed: a dispatch failure must never break the storage operation that
|
|
18
|
+
* triggered it (Requirement 17.4). Equally, when no queue bridge is configured
|
|
19
|
+
* the facade holds no publisher and job dispatch is a complete no-op — storage
|
|
20
|
+
* operations proceed unaffected (Requirement 17.3). This mirrors the
|
|
21
|
+
* graceful-degradation guarantee the Events and Realtime bridges also uphold.
|
|
22
|
+
*
|
|
23
|
+
* The facade constructs a {@link StorageQueuePublisher} via
|
|
24
|
+
* {@link bridgeStorageQueue} only when `config.bridges?.queue` is provided.
|
|
25
|
+
*
|
|
26
|
+
* _Requirements: 17.1, 17.2, 17.3, 17.4, 28.3_
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Isolate a single dispatch call. A synchronous throw is caught; a returned
|
|
30
|
+
* promise has its rejection swallowed. Either way nothing propagates back to the
|
|
31
|
+
* storage operation that triggered the job, satisfying the "never throw into the
|
|
32
|
+
* operation path" guarantee (Requirement 17.4).
|
|
33
|
+
*/
|
|
34
|
+
function safeDispatch(queue, job, payload) {
|
|
35
|
+
try {
|
|
36
|
+
const result = queue.dispatch(job, payload);
|
|
37
|
+
if (result !== undefined && result !== null && typeof result.then === "function") {
|
|
38
|
+
// Fire-and-forget: absorb any asynchronous rejection.
|
|
39
|
+
result.then(undefined, () => {
|
|
40
|
+
/* swallow — a dispatch failure must not break the storage op */
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// swallow — a dispatch failure must not break the storage op
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create a {@link StorageQueuePublisher} that dispatches background jobs through
|
|
50
|
+
* the supplied structural {@link QueueLike} bridge.
|
|
51
|
+
*
|
|
52
|
+
* The returned publisher is what the facade wires into any heavy, out-of-band
|
|
53
|
+
* work (thumbnail generation, virus scanning, OCR, PDF processing, transcoding,
|
|
54
|
+
* image optimization, archive creation). Every method is guaranteed never to
|
|
55
|
+
* throw into the caller.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* const publisher = bridgeStorageQueue(queue);
|
|
59
|
+
* publisher.thumbnail("photo.png"); // dispatches "storage.thumbnail" — never throws
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export function bridgeStorageQueue(queue) {
|
|
63
|
+
const dispatch = (job, payload) => {
|
|
64
|
+
safeDispatch(queue, job, payload);
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
dispatch,
|
|
68
|
+
thumbnail(key, options) {
|
|
69
|
+
dispatch("storage.thumbnail", { key, options });
|
|
70
|
+
},
|
|
71
|
+
virusScan(key, options) {
|
|
72
|
+
dispatch("storage.virus-scan", { key, options });
|
|
73
|
+
},
|
|
74
|
+
ocr(key, options) {
|
|
75
|
+
dispatch("storage.ocr", { key, options });
|
|
76
|
+
},
|
|
77
|
+
pdfProcess(key, options) {
|
|
78
|
+
dispatch("storage.pdf-process", { key, options });
|
|
79
|
+
},
|
|
80
|
+
transcode(key, options) {
|
|
81
|
+
dispatch("storage.transcode", { key, options });
|
|
82
|
+
},
|
|
83
|
+
imageOptimize(key, options) {
|
|
84
|
+
dispatch("storage.image-optimize", { key, options });
|
|
85
|
+
},
|
|
86
|
+
archive(key, options) {
|
|
87
|
+
dispatch("storage.archive", { key, options });
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/integrations/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAsEH;;;;;GAKG;AACH,SAAS,YAAY,CAAC,KAAgB,EAAE,GAAmB,EAAE,OAA0B;IACrF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAQ,MAAwB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACpG,sDAAsD;YACrD,MAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC7C,gEAAgE;YAClE,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IACjD,MAAM,QAAQ,GAAG,CAAC,GAAmB,EAAE,OAA0B,EAAQ,EAAE;QACzE,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ;QACR,SAAS,CAAC,GAAG,EAAE,OAAO;YACpB,QAAQ,CAAC,mBAAmB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,SAAS,CAAC,GAAG,EAAE,OAAO;YACpB,QAAQ,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,GAAG,CAAC,GAAG,EAAE,OAAO;YACd,QAAQ,CAAC,aAAa,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,UAAU,CAAC,GAAG,EAAE,OAAO;YACrB,QAAQ,CAAC,qBAAqB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,SAAS,CAAC,GAAG,EAAE,OAAO;YACpB,QAAQ,CAAC,mBAAmB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,aAAa,CAAC,GAAG,EAAE,OAAO;YACxB,QAAQ,CAAC,wBAAwB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,OAAO;YAClB,QAAQ,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Realtime integration bridge.
|
|
3
|
+
*
|
|
4
|
+
* This module broadcasts live upload-lifecycle events — `upload.started`,
|
|
5
|
+
* `upload.progress`, `upload.completed`, `upload.failed` — as an upload changes
|
|
6
|
+
* state, so connected clients can display live progress (Requirement 19.1).
|
|
7
|
+
* Each broadcast goes out through the minimal {@link RealtimeLike} shape
|
|
8
|
+
* declared in `types.ts` (any object exposing
|
|
9
|
+
* `broadcast(channel, event, payload)`), never through the concrete
|
|
10
|
+
* `@streetjs/realtime` package, so there is no hard dependency and no circular
|
|
11
|
+
* dependency (Requirements 19.2, 28.3). {@link RealtimeLike} is re-exported here
|
|
12
|
+
* for convenience; it is intentionally the single definition that lives in
|
|
13
|
+
* `types.ts`.
|
|
14
|
+
*
|
|
15
|
+
* **Never throws into the operation path.** Every broadcast is wrapped so that a
|
|
16
|
+
* synchronous throw or an asynchronous rejection from the underlying realtime
|
|
17
|
+
* layer is swallowed: a broadcast failure must never break the upload that
|
|
18
|
+
* triggered it (Requirement 19.3). Equally, when no realtime bridge is
|
|
19
|
+
* configured the facade holds no publisher and broadcasting is a complete no-op
|
|
20
|
+
* — uploads proceed unaffected (Requirement 19.3). This mirrors the
|
|
21
|
+
* graceful-degradation guarantee the Events and Queue bridges also uphold.
|
|
22
|
+
*
|
|
23
|
+
* The facade constructs a {@link StorageRealtimePublisher} via
|
|
24
|
+
* {@link bridgeStorageRealtime} only when `config.bridges?.realtime` is
|
|
25
|
+
* provided.
|
|
26
|
+
*
|
|
27
|
+
* _Requirements: 19.1, 19.2, 19.3, 28.3_
|
|
28
|
+
*/
|
|
29
|
+
import type { RealtimeLike } from "../types.js";
|
|
30
|
+
export type { RealtimeLike } from "../types.js";
|
|
31
|
+
/**
|
|
32
|
+
* The channel every upload-lifecycle event is broadcast on. A single channel
|
|
33
|
+
* keeps the client subscription surface simple; the typed
|
|
34
|
+
* {@link StorageRealtimeEventName} distinguishes the state transitions, and the
|
|
35
|
+
* payload's `key` distinguishes the upload.
|
|
36
|
+
*/
|
|
37
|
+
export declare const STORAGE_UPLOAD_CHANNEL: "storage.uploads";
|
|
38
|
+
/**
|
|
39
|
+
* The exhaustive set of upload-lifecycle event names the storage framework
|
|
40
|
+
* broadcasts (Requirement 19.1). Every upload state transition maps onto
|
|
41
|
+
* exactly one of these names.
|
|
42
|
+
*/
|
|
43
|
+
export type StorageRealtimeEventName = "upload.started" | "upload.progress" | "upload.completed" | "upload.failed";
|
|
44
|
+
/**
|
|
45
|
+
* The payload broadcast with every upload-lifecycle event. It always carries the
|
|
46
|
+
* affected object `key` and, depending on the transition, optional progress
|
|
47
|
+
* counters or an error description.
|
|
48
|
+
*/
|
|
49
|
+
export interface StorageRealtimeEventPayload {
|
|
50
|
+
/** The affected object key (always present). */
|
|
51
|
+
readonly key: string;
|
|
52
|
+
/** Bytes transferred so far, present on `upload.progress`. */
|
|
53
|
+
readonly bytesTransferred?: number;
|
|
54
|
+
/** Total expected bytes when known, present on `upload.progress`. */
|
|
55
|
+
readonly totalBytes?: number;
|
|
56
|
+
/** A human-readable failure reason, present on `upload.failed`. */
|
|
57
|
+
readonly error?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The publisher the facade holds and calls at each upload state transition.
|
|
61
|
+
* Every method is fire-and-forget and guaranteed never to throw into the caller:
|
|
62
|
+
* the underlying broadcast is isolated so a failing (or absent) realtime layer
|
|
63
|
+
* cannot break an upload (Requirement 19.3).
|
|
64
|
+
*/
|
|
65
|
+
export interface StorageRealtimePublisher {
|
|
66
|
+
/**
|
|
67
|
+
* Broadcast an already-named upload event with the given payload. Never
|
|
68
|
+
* throws. The typed convenience methods below are thin wrappers over this.
|
|
69
|
+
*/
|
|
70
|
+
broadcast(event: StorageRealtimeEventName, payload: StorageRealtimeEventPayload): void;
|
|
71
|
+
/** Broadcast `upload.started` when an upload begins. */
|
|
72
|
+
started(key: string): void;
|
|
73
|
+
/** Broadcast `upload.progress` as bytes transfer. */
|
|
74
|
+
progress(key: string, bytesTransferred: number, totalBytes?: number): void;
|
|
75
|
+
/** Broadcast `upload.completed` when an upload finishes successfully. */
|
|
76
|
+
completed(key: string): void;
|
|
77
|
+
/** Broadcast `upload.failed` when an upload errors out. */
|
|
78
|
+
failed(key: string, error?: string): void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a {@link StorageRealtimePublisher} that broadcasts upload-lifecycle
|
|
82
|
+
* events through the supplied structural {@link RealtimeLike} bridge.
|
|
83
|
+
*
|
|
84
|
+
* The returned publisher is what the facade wires into its streaming/resumable
|
|
85
|
+
* upload paths (`putStream`/`resumeUpload` → started/completed, and failed on
|
|
86
|
+
* error). Every method is guaranteed never to throw into the caller.
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* const publisher = bridgeStorageRealtime(realtime);
|
|
90
|
+
* publisher.started("video.mp4"); // broadcasts "upload.started" — never throws
|
|
91
|
+
* publisher.completed("video.mp4"); // broadcasts "upload.completed" — never throws
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function bridgeStorageRealtime(realtime: RealtimeLike): StorageRealtimePublisher;
|
|
95
|
+
//# sourceMappingURL=realtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/integrations/realtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAG,iBAA0B,CAAC;AAEjE;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAChC,gBAAgB,GAChB,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,qEAAqE;IACrE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,wBAAwB,EAAE,OAAO,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAEvF,wDAAwD;IACxD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E,yEAAyE;IACzE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B,2DAA2D;IAC3D,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AA0BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,wBAAwB,CAoBtF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the Realtime integration bridge.
|
|
3
|
+
*
|
|
4
|
+
* This module broadcasts live upload-lifecycle events — `upload.started`,
|
|
5
|
+
* `upload.progress`, `upload.completed`, `upload.failed` — as an upload changes
|
|
6
|
+
* state, so connected clients can display live progress (Requirement 19.1).
|
|
7
|
+
* Each broadcast goes out through the minimal {@link RealtimeLike} shape
|
|
8
|
+
* declared in `types.ts` (any object exposing
|
|
9
|
+
* `broadcast(channel, event, payload)`), never through the concrete
|
|
10
|
+
* `@streetjs/realtime` package, so there is no hard dependency and no circular
|
|
11
|
+
* dependency (Requirements 19.2, 28.3). {@link RealtimeLike} is re-exported here
|
|
12
|
+
* for convenience; it is intentionally the single definition that lives in
|
|
13
|
+
* `types.ts`.
|
|
14
|
+
*
|
|
15
|
+
* **Never throws into the operation path.** Every broadcast is wrapped so that a
|
|
16
|
+
* synchronous throw or an asynchronous rejection from the underlying realtime
|
|
17
|
+
* layer is swallowed: a broadcast failure must never break the upload that
|
|
18
|
+
* triggered it (Requirement 19.3). Equally, when no realtime bridge is
|
|
19
|
+
* configured the facade holds no publisher and broadcasting is a complete no-op
|
|
20
|
+
* — uploads proceed unaffected (Requirement 19.3). This mirrors the
|
|
21
|
+
* graceful-degradation guarantee the Events and Queue bridges also uphold.
|
|
22
|
+
*
|
|
23
|
+
* The facade constructs a {@link StorageRealtimePublisher} via
|
|
24
|
+
* {@link bridgeStorageRealtime} only when `config.bridges?.realtime` is
|
|
25
|
+
* provided.
|
|
26
|
+
*
|
|
27
|
+
* _Requirements: 19.1, 19.2, 19.3, 28.3_
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* The channel every upload-lifecycle event is broadcast on. A single channel
|
|
31
|
+
* keeps the client subscription surface simple; the typed
|
|
32
|
+
* {@link StorageRealtimeEventName} distinguishes the state transitions, and the
|
|
33
|
+
* payload's `key` distinguishes the upload.
|
|
34
|
+
*/
|
|
35
|
+
export const STORAGE_UPLOAD_CHANNEL = "storage.uploads";
|
|
36
|
+
/**
|
|
37
|
+
* Isolate a single broadcast call. A synchronous throw is caught; a returned
|
|
38
|
+
* promise has its rejection swallowed. Either way nothing propagates back to the
|
|
39
|
+
* upload that triggered the event, satisfying the "never throw into the
|
|
40
|
+
* operation path" guarantee (Requirement 19.3).
|
|
41
|
+
*/
|
|
42
|
+
function safeBroadcast(realtime, event, payload) {
|
|
43
|
+
try {
|
|
44
|
+
const result = realtime.broadcast(STORAGE_UPLOAD_CHANNEL, event, payload);
|
|
45
|
+
if (result !== undefined && result !== null && typeof result.then === "function") {
|
|
46
|
+
// Fire-and-forget: absorb any asynchronous rejection.
|
|
47
|
+
result.then(undefined, () => {
|
|
48
|
+
/* swallow — a broadcast failure must not break the upload */
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// swallow — a broadcast failure must not break the upload
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a {@link StorageRealtimePublisher} that broadcasts upload-lifecycle
|
|
58
|
+
* events through the supplied structural {@link RealtimeLike} bridge.
|
|
59
|
+
*
|
|
60
|
+
* The returned publisher is what the facade wires into its streaming/resumable
|
|
61
|
+
* upload paths (`putStream`/`resumeUpload` → started/completed, and failed on
|
|
62
|
+
* error). Every method is guaranteed never to throw into the caller.
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* const publisher = bridgeStorageRealtime(realtime);
|
|
66
|
+
* publisher.started("video.mp4"); // broadcasts "upload.started" — never throws
|
|
67
|
+
* publisher.completed("video.mp4"); // broadcasts "upload.completed" — never throws
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export function bridgeStorageRealtime(realtime) {
|
|
71
|
+
const broadcast = (event, payload) => {
|
|
72
|
+
safeBroadcast(realtime, event, payload);
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
broadcast,
|
|
76
|
+
started(key) {
|
|
77
|
+
broadcast("upload.started", { key });
|
|
78
|
+
},
|
|
79
|
+
progress(key, bytesTransferred, totalBytes) {
|
|
80
|
+
broadcast("upload.progress", { key, bytesTransferred, totalBytes });
|
|
81
|
+
},
|
|
82
|
+
completed(key) {
|
|
83
|
+
broadcast("upload.completed", { key });
|
|
84
|
+
},
|
|
85
|
+
failed(key, error) {
|
|
86
|
+
broadcast("upload.failed", { key, error });
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=realtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../src/integrations/realtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,iBAA0B,CAAC;AAuDjE;;;;;GAKG;AACH,SAAS,aAAa,CACpB,QAAsB,EACtB,KAA+B,EAC/B,OAAoC;IAEpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1E,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAQ,MAAwB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACpG,sDAAsD;YACrD,MAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC7C,6DAA6D;YAC/D,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;IAC5D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAsB;IAC1D,MAAM,SAAS,GAAG,CAAC,KAA+B,EAAE,OAAoC,EAAQ,EAAE;QAChG,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,OAAO;QACL,SAAS;QACT,OAAO,CAAC,GAAG;YACT,SAAS,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACvC,CAAC;QACD,QAAQ,CAAC,GAAG,EAAE,gBAAgB,EAAE,UAAU;YACxC,SAAS,CAAC,iBAAiB,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,SAAS,CAAC,GAAG;YACX,SAAS,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,KAAK;YACf,SAAS,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @streetjs/storage — the lifecycle engine.
|
|
3
|
+
*
|
|
4
|
+
* Lifecycle rules act on objects automatically based on their age or state, so
|
|
5
|
+
* stored objects are cleaned up, archived, or tiered over time (Requirement
|
|
6
|
+
* 13). {@link LifecycleEngine} evaluates a single {@link LifecycleRule} and
|
|
7
|
+
* applies its action to every qualifying object in a **provider-agnostic** way:
|
|
8
|
+
*
|
|
9
|
+
* - When the backing {@link StorageDriver} implements the optional native
|
|
10
|
+
* `lifecycle` capability, the engine delegates evaluation to the driver so a
|
|
11
|
+
* provider with first-class lifecycle policies (e.g. S3 lifecycle
|
|
12
|
+
* configuration) is used directly.
|
|
13
|
+
* - Otherwise the engine **simulates** the rule over the mandatory driver
|
|
14
|
+
* primitives (`list`/`stat`/`get`/`put`/`delete`). It enumerates candidate
|
|
15
|
+
* keys with `list`, reads each object's `createdAt` with `stat`, computes the
|
|
16
|
+
* object's age relative to the injected {@link Clock}, and applies the rule's
|
|
17
|
+
* action to the objects whose age meets the rule's threshold. This is what
|
|
18
|
+
* lets the zero-dependency drivers simulate lifecycle entirely in memory /
|
|
19
|
+
* over the local filesystem (Requirement 13.3).
|
|
20
|
+
*
|
|
21
|
+
* Supported rule types (Requirement 13.1):
|
|
22
|
+
* - `delete-after-days` — delete objects older than `days`.
|
|
23
|
+
* - `archive-after-months` — archive objects older than `months` by relocating
|
|
24
|
+
* them under the reserved {@link ARCHIVE_KEY_PREFIX}.
|
|
25
|
+
* - `expire-temp-uploads` — delete transient multipart-part / resumable-session
|
|
26
|
+
* state older than `afterMs` (the reserved temp-upload key spaces).
|
|
27
|
+
* - `move-to-cold` — relocate objects older than `afterDays` under `coldPrefix`.
|
|
28
|
+
*
|
|
29
|
+
* **Exactly-once (Requirement 13.2).** Each action removes the qualifying object
|
|
30
|
+
* from the space that a subsequent evaluation scans: `delete`/`expire` remove
|
|
31
|
+
* the object outright, and `archive`/`move-to-cold` relocate it to a prefix that
|
|
32
|
+
* the scan excludes (the reserved archive prefix, or `coldPrefix`). Because the
|
|
33
|
+
* relocated copy is written with a fresh `createdAt` at the evaluation instant,
|
|
34
|
+
* it is also too young to re-qualify at the same `now`. The net effect is that a
|
|
35
|
+
* second evaluation produces no further action on an already-actioned object.
|
|
36
|
+
*
|
|
37
|
+
* The module depends only on the driver contract, the shared type surface, the
|
|
38
|
+
* metadata layer, and the core `Clock`, keeping the dependency direction
|
|
39
|
+
* acyclic. Event publication for applied actions (Requirement 13.4) is wired
|
|
40
|
+
* separately by the Events bridge (task 21.1); this engine only performs the
|
|
41
|
+
* actions and returns their {@link LifecycleOutcome} descriptors.
|
|
42
|
+
*
|
|
43
|
+
* _Requirements: 13.1, 13.2, 13.3_
|
|
44
|
+
*/
|
|
45
|
+
import { type Clock } from "streetjs";
|
|
46
|
+
import type { StorageDriver } from "./driver.js";
|
|
47
|
+
import type { LifecycleOutcome, LifecycleRule } from "./types.js";
|
|
48
|
+
/**
|
|
49
|
+
* Reserved key prefix under which objects archived by an `archive-after-months`
|
|
50
|
+
* rule are relocated. An archived `<key>` lives at `${ARCHIVE_KEY_PREFIX}<key>`.
|
|
51
|
+
* The prefix is excluded from every lifecycle scan so an archived object is
|
|
52
|
+
* never re-actioned (Requirement 13.2).
|
|
53
|
+
*/
|
|
54
|
+
export declare const ARCHIVE_KEY_PREFIX = ".archive/";
|
|
55
|
+
/** Options for constructing a {@link LifecycleEngine}. */
|
|
56
|
+
export interface LifecycleEngineOptions {
|
|
57
|
+
/** The driver every action is delegated to or simulated over. */
|
|
58
|
+
readonly driver: StorageDriver;
|
|
59
|
+
/**
|
|
60
|
+
* Injected clock used to compute object age at evaluation time. Default
|
|
61
|
+
* `systemClock`, so time is deterministic in tests (Requirement 13.3).
|
|
62
|
+
*/
|
|
63
|
+
readonly clock?: Clock;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Provider-agnostic lifecycle engine built on the driver contract.
|
|
67
|
+
*
|
|
68
|
+
* A single instance is held by the facade and bound to one {@link StorageDriver}
|
|
69
|
+
* for its lifetime, so the native-vs-simulated decision (based on whether the
|
|
70
|
+
* driver exposes a `lifecycle` capability) is stable across every call.
|
|
71
|
+
*/
|
|
72
|
+
export declare class LifecycleEngine {
|
|
73
|
+
/** The driver every action is delegated to or simulated over. */
|
|
74
|
+
private readonly driver;
|
|
75
|
+
/** Injected clock used to compute object age at evaluation time. */
|
|
76
|
+
private readonly clock;
|
|
77
|
+
constructor(options: LifecycleEngineOptions);
|
|
78
|
+
/** The driver's native lifecycle capability, when present. */
|
|
79
|
+
private get native();
|
|
80
|
+
/**
|
|
81
|
+
* Evaluate `rule` against the current object set and apply its action to every
|
|
82
|
+
* qualifying object, returning one {@link LifecycleOutcome} per actioned
|
|
83
|
+
* object (Requirements 13.1, 13.2). Object age is measured relative to `now`,
|
|
84
|
+
* which defaults to the injected clock. When the driver exposes a native
|
|
85
|
+
* `lifecycle` capability the evaluation is delegated to it; otherwise the rule
|
|
86
|
+
* is simulated over the driver primitives.
|
|
87
|
+
*/
|
|
88
|
+
apply(rule: LifecycleRule, now?: number): Promise<LifecycleOutcome[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Delete every managed object under `prefix` whose age is at least
|
|
91
|
+
* `thresholdMs`. The deletion removes the object from the scanned space, so a
|
|
92
|
+
* repeated evaluation finds nothing further to delete (Requirement 13.2).
|
|
93
|
+
*/
|
|
94
|
+
private applyDelete;
|
|
95
|
+
/**
|
|
96
|
+
* Archive every managed object under `prefix` whose age is at least
|
|
97
|
+
* `thresholdMs` by relocating it under {@link ARCHIVE_KEY_PREFIX}. The archive
|
|
98
|
+
* prefix is excluded from the scan, so an archived object is never re-archived
|
|
99
|
+
* (Requirement 13.2).
|
|
100
|
+
*/
|
|
101
|
+
private applyArchive;
|
|
102
|
+
/**
|
|
103
|
+
* Expire (delete) transient upload state older than `afterMs` across the
|
|
104
|
+
* reserved temp-upload key spaces (multipart parts and resumable session
|
|
105
|
+
* bytes). Because expiration deletes the state, a repeated evaluation finds
|
|
106
|
+
* nothing further to expire (Requirement 13.2).
|
|
107
|
+
*/
|
|
108
|
+
private applyExpire;
|
|
109
|
+
/**
|
|
110
|
+
* Relocate every managed object under `prefix` whose age is at least
|
|
111
|
+
* `thresholdMs` to `${coldPrefix}<key>`. Keys already residing under
|
|
112
|
+
* `coldPrefix` are excluded from the scan, so a repeated evaluation does not
|
|
113
|
+
* move an already-tiered object again (Requirement 13.2).
|
|
114
|
+
*/
|
|
115
|
+
private applyMoveToCold;
|
|
116
|
+
/**
|
|
117
|
+
* List candidate keys under `prefix`, keep those accepted by `accept`, and
|
|
118
|
+
* return the subset whose age (`now - createdAt`, read via `stat`) is at least
|
|
119
|
+
* `thresholdMs`. Keys that vanish between `list` and `stat` are skipped.
|
|
120
|
+
*/
|
|
121
|
+
private collectQualifying;
|
|
122
|
+
/**
|
|
123
|
+
* Move the object at `sourceKey` to `destinationKey` over the driver
|
|
124
|
+
* primitives: the content and preserved write-time metadata are written to the
|
|
125
|
+
* destination and the source is then removed. Returns `false` without writing
|
|
126
|
+
* when the source has vanished.
|
|
127
|
+
*/
|
|
128
|
+
private relocate;
|
|
129
|
+
/**
|
|
130
|
+
* Report whether `key` is an application-visible object (as opposed to
|
|
131
|
+
* internal bookkeeping such as version snapshots, multipart parts, resumable
|
|
132
|
+
* session bytes, or already-archived copies). Age-based rules act only on
|
|
133
|
+
* managed keys.
|
|
134
|
+
*/
|
|
135
|
+
private isManagedKey;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAEnD,OAAO,KAAK,EAAuB,aAAa,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAalE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAwB9C,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IAEvC,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;gBAElB,OAAO,EAAE,sBAAsB;IAK3C,8DAA8D;IAC9D,OAAO,KAAK,MAAM,GAEjB;IAED;;;;;;;OAOG;IACG,KAAK,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,GAAE,MAAqB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAsBzF;;;;OAIG;YACW,WAAW;IAgBzB;;;;;OAKG;YACW,YAAY;IAkB1B;;;;;OAKG;YACW,WAAW;IAczB;;;;;OAKG;YACW,eAAe;IAsB7B;;;;OAIG;YACW,iBAAiB;IAuB/B;;;;;OAKG;YACW,QAAQ;IAUtB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CAGrB"}
|