@dereekb/firebase 13.11.2 → 13.11.3

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 (75) hide show
  1. package/index.cjs.js +2440 -575
  2. package/index.esm.js +2419 -579
  3. package/package.json +5 -5
  4. package/src/lib/client/firestore/array.d.ts +1 -0
  5. package/src/lib/client/firestore/driver.accessor.batch.d.ts +1 -0
  6. package/src/lib/client/firestore/driver.accessor.create.d.ts +1 -0
  7. package/src/lib/client/firestore/driver.accessor.d.ts +1 -0
  8. package/src/lib/client/firestore/driver.accessor.default.d.ts +1 -0
  9. package/src/lib/client/firestore/driver.accessor.transaction.d.ts +1 -0
  10. package/src/lib/client/firestore/increment.d.ts +1 -0
  11. package/src/lib/client/function/development.function.factory.d.ts +1 -0
  12. package/src/lib/client/function/function.factory.d.ts +2 -0
  13. package/src/lib/client/function/model.function.factory.d.ts +1 -0
  14. package/src/lib/common/firestore/accessor/accessor.d.ts +1 -0
  15. package/src/lib/common/firestore/accessor/accessor.wrap.d.ts +1 -0
  16. package/src/lib/common/firestore/accessor/accessor.wrap.modify.d.ts +4 -0
  17. package/src/lib/common/firestore/accessor/array.d.ts +1 -0
  18. package/src/lib/common/firestore/accessor/document.d.ts +4 -0
  19. package/src/lib/common/firestore/accessor/document.paged.d.ts +134 -0
  20. package/src/lib/common/firestore/accessor/document.utility.d.ts +195 -0
  21. package/src/lib/common/firestore/accessor/increment.d.ts +1 -0
  22. package/src/lib/common/firestore/accessor/index.d.ts +1 -0
  23. package/src/lib/common/firestore/cache/cache.d.ts +1 -0
  24. package/src/lib/common/firestore/cache/cache.memory.d.ts +3 -0
  25. package/src/lib/common/firestore/collection/collection.d.ts +29 -2
  26. package/src/lib/common/firestore/collection/collection.group.d.ts +1 -0
  27. package/src/lib/common/firestore/collection/collection.query.d.ts +1 -0
  28. package/src/lib/common/firestore/collection/collection.single.d.ts +1 -0
  29. package/src/lib/common/firestore/collection/collection.util.d.ts +1 -0
  30. package/src/lib/common/firestore/collection/index.d.ts +1 -0
  31. package/src/lib/common/firestore/collection/subcollection.d.ts +1 -0
  32. package/src/lib/common/firestore/collection/subcollection.paged.d.ts +226 -0
  33. package/src/lib/common/firestore/collection/subcollection.single.d.ts +1 -0
  34. package/src/lib/common/firestore/context.d.ts +37 -1
  35. package/src/lib/common/firestore/driver/query.handler.d.ts +1 -0
  36. package/src/lib/common/firestore/error.d.ts +1 -0
  37. package/src/lib/common/firestore/query/constraint.d.ts +2 -0
  38. package/src/lib/common/firestore/query/iterator.d.ts +5 -0
  39. package/src/lib/common/firestore/query/query.d.ts +1 -0
  40. package/src/lib/common/firestore/snapshot/snapshot.d.ts +1 -0
  41. package/src/lib/common/firestore/snapshot/snapshot.field.d.ts +262 -0
  42. package/src/lib/common/firestore/util/id.batch.d.ts +1 -0
  43. package/src/lib/common/model/function.d.ts +1 -0
  44. package/src/lib/common/model/model.service.d.ts +8 -0
  45. package/src/lib/common/model/permission/permission.service.d.ts +1 -0
  46. package/src/lib/common/model/permission/permission.service.grant.d.ts +6 -0
  47. package/src/lib/common/storage/accessor/path.model.d.ts +1 -0
  48. package/src/lib/common/storage/context.d.ts +1 -0
  49. package/src/lib/common/storage/driver/accessor.iterate.d.ts +1 -0
  50. package/src/lib/common/storage/driver/list.d.ts +1 -0
  51. package/src/lib/common/storage/storage.d.ts +1 -0
  52. package/src/lib/model/notification/index.d.ts +2 -0
  53. package/src/lib/model/notification/notification.api.d.ts +36 -1
  54. package/src/lib/model/notification/notification.config.d.ts +1 -0
  55. package/src/lib/model/notification/notification.create.d.ts +2 -0
  56. package/src/lib/model/notification/notification.create.loggedevent.d.ts +33 -0
  57. package/src/lib/model/notification/notification.create.task.d.ts +1 -0
  58. package/src/lib/model/notification/notification.d.ts +179 -3
  59. package/src/lib/model/notification/notification.details.d.ts +1 -0
  60. package/src/lib/model/notification/notification.id.d.ts +23 -1
  61. package/src/lib/model/notification/notification.loggedevent.loader.d.ts +82 -0
  62. package/src/lib/model/notification/notification.message.d.ts +2 -0
  63. package/src/lib/model/notification/notification.query.d.ts +17 -0
  64. package/src/lib/model/notification/notification.util.d.ts +12 -1
  65. package/src/lib/model/storagefile/storagefile.create.d.ts +1 -0
  66. package/src/lib/model/storagefile/storagefile.d.ts +1 -0
  67. package/src/lib/model/storagefile/storagefile.file.d.ts +1 -0
  68. package/src/lib/model/storagefile/storagefile.permission.d.ts +1 -0
  69. package/src/lib/model/storagefile/storagefile.upload.d.ts +2 -0
  70. package/src/lib/model/storagefile/storagefile.upload.determiner.d.ts +2 -0
  71. package/test/index.cjs.js +1038 -1
  72. package/test/index.esm.js +1031 -3
  73. package/test/package.json +6 -6
  74. package/test/src/lib/common/mock/mock.item.d.ts +119 -2
  75. package/test/src/lib/common/mock/mock.item.service.d.ts +21 -1
@@ -47,6 +47,7 @@ export interface FirebaseModelServiceConfig<C extends FirebaseModelServiceContex
47
47
  * roleMapForModel: (output, context, model) => computeRoles(output, context)
48
48
  * });
49
49
  * ```
50
+ * @__NO_SIDE_EFFECTS__
50
51
  */
51
52
  export declare function firebaseModelService<C extends FirebaseModelServiceContext, T, D extends FirestoreDocument<T> = FirestoreDocument<T>, R extends GrantedRole = GrantedRole>(config: FirebaseModelServiceConfig<C, T, D, R>): FirebaseModelService<C, T, D, R>;
52
53
  /**
@@ -58,6 +59,7 @@ export type FirebaseModelServiceFactory<C extends FirebaseModelServiceContext, T
58
59
  *
59
60
  * @param config - the service configuration
60
61
  * @returns a {@link FirebaseModelServiceFactory} that lazily creates and caches the service
62
+ * @__NO_SIDE_EFFECTS__
61
63
  */
62
64
  export declare function firebaseModelServiceFactory<C extends FirebaseModelServiceContext, T, D extends FirestoreDocument<T> = FirestoreDocument<T>, R extends GrantedRole = GrantedRole>(config: FirebaseModelServiceConfig<C, T, D, R>): FirebaseModelServiceFactory<C, T, D, R>;
63
65
  /**
@@ -104,6 +106,7 @@ export type InModelContextFirebaseModelServiceUseFunction<C extends FirebasePerm
104
106
  *
105
107
  * @param factory - lazy getter for the underlying model service
106
108
  * @returns an {@link InContextFirebaseModelServiceFactory} that binds contexts to the service
109
+ * @__NO_SIDE_EFFECTS__
107
110
  */
108
111
  export declare function inContextFirebaseModelServiceFactory<C extends FirebaseModelServiceContext, T, D extends FirestoreDocument<T> = FirestoreDocument<T>, R extends GrantedRole = GrantedRole>(factory: FirebaseModelServiceGetter<C, T, D, R>): InContextFirebaseModelServiceFactory<C, T, D, R>;
109
112
  /**
@@ -145,6 +148,7 @@ export type FirebaseModelsServiceTypes<S extends FirebaseModelsService<any, any>
145
148
  *
146
149
  * @param services - the map of model service getter factories
147
150
  * @returns a {@link FirebaseModelsService} that dispatches to the appropriate model service by type
151
+ * @__NO_SIDE_EFFECTS__
148
152
  */
149
153
  export declare function firebaseModelsService<X extends FirebaseModelsServiceFactory<C, I>, C extends FirebaseModelServiceContext, I extends FirestoreModelIdentity = FirestoreModelIdentity>(services: X): FirebaseModelsService<X, C>;
150
154
  /**
@@ -162,6 +166,7 @@ export type InContextFirebaseModelsServiceFactory<Y> = FirebaseModelsServiceType
162
166
  *
163
167
  * @param service - the multi-model service to wrap
164
168
  * @returns an {@link InContextFirebaseModelsServiceFactory} that binds a context to the service
169
+ * @__NO_SIDE_EFFECTS__
165
170
  */
166
171
  export declare function inContextFirebaseModelsServiceFactory<X extends FirebaseModelsServiceFactory<C, I>, C extends FirebaseModelServiceContext, I extends FirestoreModelIdentity = FirestoreModelIdentity>(service: FirebaseModelsService<X, C>): InContextFirebaseModelsServiceFactory<FirebaseModelsService<X, C>>;
167
172
  /**
@@ -186,6 +191,7 @@ export type UseFirebaseModelsServiceSelectionUseFunction<Y extends FirebaseModel
186
191
  * @param type - the model type to select
187
192
  * @param select - selection params including context and key
188
193
  * @returns the {@link FirebaseModelsServiceSelectionResult} bound to the specified model
194
+ * @__NO_SIDE_EFFECTS__
189
195
  */
190
196
  export declare function selectFromFirebaseModelsService<Y extends FirebaseModelsService<any, any>, T extends FirebaseModelsServiceTypes<Y>>(service: Y, type: T, select: FirebaseModelsServiceSelection<Y, T>): FirebaseModelsServiceSelectionResult<Y, T>;
191
197
  /**
@@ -197,6 +203,7 @@ export declare function selectFromFirebaseModelsService<Y extends FirebaseModels
197
203
  * @param type - the model type to select
198
204
  * @param select - selection params including context, key, and optional role requirements
199
205
  * @returns a {@link UsePromiseFunction} for the resolved roles reader
206
+ * @__NO_SIDE_EFFECTS__
200
207
  */
201
208
  export declare function useFirebaseModelsService<Y extends FirebaseModelsService<any, any>, T extends FirebaseModelsServiceTypes<Y>>(service: Y, type: T, select: UseFirebaseModelsServiceSelection<Y, T>): UseFirebaseModelsServiceSelectionResult<Y, T>;
202
209
  /**
@@ -206,5 +213,6 @@ export declare function useFirebaseModelsService<Y extends FirebaseModelsService
206
213
  *
207
214
  * @param inContextFirebaseModelsService - context-bound multi-model service
208
215
  * @returns a map of collection type strings to their {@link FirestoreModelIdentity} objects
216
+ * @__NO_SIDE_EFFECTS__
209
217
  */
210
218
  export declare function buildFirebaseCollectionTypeModelTypeMap<Y extends FirebaseModelsService<any, any>>(inContextFirebaseModelsService: InContextFirebaseModelsService<Y>): import("..").FirestoreModelIdentityTypeMap;
@@ -36,6 +36,7 @@ export declare class FirebaseModelPermissionServiceInstance<C extends FirebaseMo
36
36
  *
37
37
  * @param delegate - provides model loading and role computation
38
38
  * @returns a {@link FirebaseModelPermissionServiceInstance} configured with the given delegate
39
+ * @__NO_SIDE_EFFECTS__
39
40
  */
40
41
  export declare function firebaseModelPermissionService<C extends FirebaseModelContext, T, D extends FirestoreDocument<T> = FirestoreDocument<T>, R extends string = string>(delegate: FirebasePermissionServiceInstanceDelegate<C, T, D, R>): FirebaseModelPermissionServiceInstance<C, T, D, R>;
41
42
  /**
@@ -23,6 +23,7 @@ export declare const isAdminInFirebaseModelContext: AsyncDecisionFunction<Fireba
23
23
  * const grantIfAdmin = grantModelRolesIfAdminFunction(fullAccessRoleMap);
24
24
  * const roles = await grantIfAdmin(context);
25
25
  * ```
26
+ * @__NO_SIDE_EFFECTS__
26
27
  */
27
28
  export declare function grantModelRolesIfAdminFunction<R extends string = string>(rolesToGrantToAdmin: GetterOrValue<GrantedRoleMap<R>>): GrantRolesIfFunction<FirebaseModelContext, R>;
28
29
  /**
@@ -44,6 +45,7 @@ export declare function grantModelRolesIfAdmin<R extends string = string>(contex
44
45
  * @param authRoles - the auth roles the user must have
45
46
  * @param rolesToGrantToAdmin - the model roles to grant if the auth roles are present
46
47
  * @returns a {@link GrantRolesIfFunction} that grants the given roles when the user has the required auth roles
48
+ * @__NO_SIDE_EFFECTS__
47
49
  */
48
50
  export declare function grantModelRolesIfHasAuthRolesFunction<R extends string = string>(authRoles: AuthRole[], rolesToGrantToAdmin: GetterOrValue<GrantedRoleMap<R>>): GrantRolesIfFunction<FirebaseModelContext, R>;
49
51
  /**
@@ -55,6 +57,7 @@ export type GrantModelRolesIfHasAuthRolesFactory = <R extends string = string>(c
55
57
  *
56
58
  * @param authRoles - the auth roles the user must have
57
59
  * @returns a {@link GrantModelRolesIfHasAuthRolesFactory} pre-configured to check the given auth roles
60
+ * @__NO_SIDE_EFFECTS__
58
61
  */
59
62
  export declare function grantModelRolesIfHasAuthRolesFactory(authRoles: IterableOrValue<AuthRole>): GrantModelRolesIfHasAuthRolesFactory;
60
63
  /**
@@ -94,6 +97,7 @@ export declare const isOwnerOfUserRelatedModelInFirebaseModelContext: AsyncDecis
94
97
  * const grantIfOwner = grantModelRolesIfAuthUserRelatedModelFunction<User>(fullAccessRoleMap);
95
98
  * const roles = await grantIfOwner({ model: userData, context });
96
99
  * ```
100
+ * @__NO_SIDE_EFFECTS__
97
101
  */
98
102
  export declare function grantModelRolesIfAuthUserRelatedModelFunction<T extends UserRelated, R extends string = string>(rolesToGrant: GetterOrValue<GrantedRoleMap<R>>): GrantRolesIfFunction<UserRelatedModelFirebaseModelContext<T>, R>;
99
103
  /**
@@ -116,6 +120,7 @@ export type GeneralGrantRolesOnlyIfFunction<C> = <R extends string = string>(con
116
120
  * @param grantIf - decision function to evaluate
117
121
  * @param grantedRoles - roles to grant if the decision is `true`
118
122
  * @returns a {@link GrantRolesOnlyIfFunction} that grants roles or returns no-access with no fallback
123
+ * @__NO_SIDE_EFFECTS__
119
124
  */
120
125
  export declare function grantModelRolesOnlyIfFunction<C, R extends string = string>(grantIf: AsyncDecisionFunction<C>, grantedRoles: GetterOrValue<GrantedRoleMap<R>>): GrantRolesOnlyIfFunction<C, R>;
121
126
  /**
@@ -152,5 +157,6 @@ export type GrantRolesOtherwiseFunction<R extends string = string> = Getter<Gran
152
157
  * );
153
158
  * const roles = await grantIfOwner(context, () => noAccessRoleMap());
154
159
  * ```
160
+ * @__NO_SIDE_EFFECTS__
155
161
  */
156
162
  export declare function grantModelRolesIfFunction<C, R extends string = string>(grantIf: AsyncDecisionFunction<C>, grantedRoles: GetterOrValue<GrantedRoleMap<R>>): GrantRolesIfFunction<C, R>;
@@ -42,5 +42,6 @@ export type ModelStorageSlashPathFactory<T extends object = object> = (input: Re
42
42
  * const path = pathFactory(userDocument, 'profile.png');
43
43
  * // path === '/model/avatars/users/abc123/profile.png'
44
44
  * ```
45
+ * @__NO_SIDE_EFFECTS__
45
46
  */
46
47
  export declare function modelStorageSlashPathFactory<T extends object = object>(config?: ModelStorageSlashPathFactoryConfig): ModelStorageSlashPathFactory<T>;
@@ -49,5 +49,6 @@ export interface FirebaseStorageContextFactoryConfig {
49
49
  * const storageContext = factory(firebaseStorage, { defaultBucketId: 'my-bucket' });
50
50
  * const file = storageContext.file('uploads/doc.pdf');
51
51
  * ```
52
+ * @__NO_SIDE_EFFECTS__
52
53
  */
53
54
  export declare function firebaseStorageContextFactory<F extends FirebaseStorage = FirebaseStorage>(drivers: FirebaseStorageDrivers): FirebaseStorageContextFactory<F>;
@@ -31,6 +31,7 @@ export type IterateStorageListFilesFactory = FetchPageFactory<IterateStorageList
31
31
  * ```ts
32
32
  * const factory = iterateStorageListFilesFactory({ maxResults: 100 });
33
33
  * ```
34
+ * @__NO_SIDE_EFFECTS__
34
35
  */
35
36
  export declare function iterateStorageListFilesFactory(config: IterateStorageListFilesFactoryConfig): IterateStorageListFilesFactory;
36
37
  /**
@@ -50,6 +50,7 @@ export type StorageListFilesResultFactory<S, R> = (input: StorageListFilesResult
50
50
  * const result = factory({ storage, folder, options: { maxResults: 50 } }, rawSdkResult);
51
51
  * const files = result.files();
52
52
  * ```
53
+ * @__NO_SIDE_EFFECTS__
53
54
  */
54
55
  export declare function storageListFilesResultFactory<S, R>(delegate: StorageListFilesResultFactoryDelegate<S, R>): StorageListFilesResultFactory<S, R>;
55
56
  /**
@@ -88,6 +88,7 @@ export interface StoragePathFactoryConfig extends StorageBucketIdRef {
88
88
  * const path = pathFactory('images/photo.png');
89
89
  * // path === { bucketId: 'my-bucket', pathString: 'images/photo.png' }
90
90
  * ```
91
+ * @__NO_SIDE_EFFECTS__
91
92
  */
92
93
  export declare function storagePathFactory(config: StoragePathFactoryConfig): StoragePathFactory;
93
94
  /**
@@ -5,6 +5,8 @@ export * from './notification.api.util';
5
5
  export * from './notification.action';
6
6
  export * from './notification.config';
7
7
  export * from './notification.create';
8
+ export * from './notification.create.loggedevent';
9
+ export * from './notification.loggedevent.loader';
8
10
  export * from './notification.create.task';
9
11
  export * from './notification.details';
10
12
  export * from './notification.item';
@@ -207,6 +207,11 @@ export interface SendNotificationResult {
207
207
  readonly notificationTemplateType: Maybe<NotificationTemplateType>;
208
208
  readonly isKnownTemplateType: Maybe<boolean>;
209
209
  readonly isNotificationTask: boolean;
210
+ /**
211
+ * True if the notification was a logged-event record (`st === LOGGED_EVENT`). Logged events bypass
212
+ * the send pipeline entirely; the factory short-circuits and returns immediately when one is loaded.
213
+ */
214
+ readonly isLoggedEvent: boolean;
210
215
  readonly isUniqueNotificationTask: boolean;
211
216
  readonly uniqueNotificationTaskConflict: boolean;
212
217
  readonly isConfiguredTemplateType: Maybe<boolean>;
@@ -242,7 +247,7 @@ export declare const sendQueuedNotificationsParamsType: Type<SendQueuedNotificat
242
247
  /**
243
248
  * Aggregate result of processing the notification send queue, with counts of visited, succeeded, failed, and deleted notifications.
244
249
  */
245
- export interface SendQueuedNotificationsResult extends Omit<SendNotificationResult, 'throttled' | 'isNotificationTask' | 'isUniqueNotificationTask' | 'notificationTaskCompletionType' | 'uniqueNotificationTaskConflict' | 'isConfiguredTemplateType' | 'isKnownTemplateType' | 'notificationTemplateType' | 'notificationMarkedDone' | 'deletedNotification' | 'createdBox' | 'success' | 'exists' | 'boxExists' | 'notificationBoxNeedsInitialization' | 'tryRun' | 'loadMessageFunctionFailure' | 'buildMessageFailure'> {
250
+ export interface SendQueuedNotificationsResult extends Omit<SendNotificationResult, 'throttled' | 'isNotificationTask' | 'isLoggedEvent' | 'isUniqueNotificationTask' | 'notificationTaskCompletionType' | 'uniqueNotificationTaskConflict' | 'isConfiguredTemplateType' | 'isKnownTemplateType' | 'notificationTemplateType' | 'notificationMarkedDone' | 'deletedNotification' | 'createdBox' | 'success' | 'exists' | 'boxExists' | 'notificationBoxNeedsInitialization' | 'tryRun' | 'loadMessageFunctionFailure' | 'buildMessageFailure'> {
246
251
  readonly excessLoopsDetected: boolean;
247
252
  readonly notificationLoopCount: number;
248
253
  readonly notificationBoxesCreated: number;
@@ -265,6 +270,34 @@ export interface CleanupSentNotificationsResult {
265
270
  readonly notificationsDeleted: number;
266
271
  readonly notificationWeeksCreated: number;
267
272
  readonly notificationWeeksUpdated: number;
273
+ /**
274
+ * Number of logged-event notifications archived to {@link NotificationLoggedEventDay} during cleanup.
275
+ */
276
+ readonly notificationLoggedEventsCleanedUp: number;
277
+ }
278
+ /**
279
+ * Parameters for the `cleanupOldNotificationLoggedEventDays` action.
280
+ */
281
+ export interface CleanupOldNotificationLoggedEventDaysParams {
282
+ /**
283
+ * Number of days of logged-event history to retain. Day documents whose ISO day string ID is older
284
+ * than `now - retentionDays` are deleted along with their nested page subcollection.
285
+ */
286
+ readonly retentionDays: number;
287
+ }
288
+ export declare const cleanupOldNotificationLoggedEventDaysParamsType: Type<CleanupOldNotificationLoggedEventDaysParams>;
289
+ /**
290
+ * Aggregate result of the `cleanupOldNotificationLoggedEventDays` action.
291
+ */
292
+ export interface CleanupOldNotificationLoggedEventDaysResult {
293
+ /**
294
+ * Number of {@link NotificationLoggedEventDay} wrapper documents deleted.
295
+ */
296
+ readonly daysDeleted: number;
297
+ /**
298
+ * Number of page documents (including the `_index` doc) deleted across all purged days.
299
+ */
300
+ readonly pagesDeleted: number;
268
301
  }
269
302
  /**
270
303
  * Custom (non-CRUD) function type map for notifications. Currently empty — all operations use the CRUD pattern.
@@ -295,6 +328,8 @@ export type NotificationBoxModelCrudFunctionsConfig = {
295
328
  };
296
329
  };
297
330
  readonly notificationWeek: null;
331
+ readonly notificationLoggedEventDay: null;
332
+ readonly notificationLoggedEventDayPage: null;
298
333
  };
299
334
  export declare const notificationBoxModelCrudFunctionsConfig: ModelFirebaseCrudFunctionConfigMap<NotificationBoxModelCrudFunctionsConfig, NotificationTypes>;
300
335
  /**
@@ -311,6 +311,7 @@ export type EncodedNotificationBoxRecipientTemplateConfigRecord = Record<Notific
311
311
  * using bitwise encoding for compact storage.
312
312
  *
313
313
  * @returns a Firestore field converter that encodes and decodes template config records using bitwise encoding
314
+ * @__NO_SIDE_EFFECTS__
314
315
  */
315
316
  export declare function firestoreNotificationBoxRecipientTemplateConfigRecord(): import("../..").FirestoreModelFieldMapFunctionsConfig<import("../..").FirestoreEncodedObjectMapFieldValueType<NotificationBoxRecipientTemplateConfig, string>, import("../..").FirestoreMapFieldType<number, string>>;
316
317
  /**
@@ -126,6 +126,7 @@ export interface CreateNotificationTemplateInput extends Partial<Omit<CreateNoti
126
126
  *
127
127
  * @param input - friendly input with readable field names
128
128
  * @returns the low-level template using Firestore field abbreviations
129
+ * @__NO_SIDE_EFFECTS__
129
130
  */
130
131
  export declare function createNotificationTemplate(input: CreateNotificationTemplateInput): CreateNotificationTemplate;
131
132
  /**
@@ -221,6 +222,7 @@ export interface CreateNotificationDocumentPairResult extends Pick<CreateNotific
221
222
  * @returns the document reference and notification data pair, with `notificationCreated` set to false
222
223
  * @throws {Error} When neither an accessor nor sufficient context is provided
223
224
  * @throws {Error} When `unique=true` but no target model is specified
225
+ * @__NO_SIDE_EFFECTS__
224
226
  */
225
227
  export declare function createNotificationDocumentPair(input: CreateNotificationDocumentPairInput): CreateNotificationDocumentPairResult;
226
228
  /**
@@ -0,0 +1,33 @@
1
+ import { type CreateNotificationTemplate, type CreateNotificationTemplateInput } from './notification.create';
2
+ /**
3
+ * Template for creating a logged-event {@link Notification}. Alias for {@link CreateNotificationTemplate}.
4
+ */
5
+ export type CreateNotificationLoggedEventTemplate = CreateNotificationTemplate;
6
+ /**
7
+ * Simplified input for creating logged-event notification templates. Omits fields not applicable to
8
+ * logged events (recipients, send type, recipient flags) and requires `notificationModel` since
9
+ * logged events are always associated with a target model.
10
+ */
11
+ export type CreateNotificationLoggedEventTemplateInput = Omit<CreateNotificationTemplateInput, 'st' | 'recipients' | 'r' | 'rf' | 'sendType'>;
12
+ /**
13
+ * Creates a {@link CreateNotificationLoggedEventTemplate} with `LOGGED_EVENT` send type and no recipients.
14
+ *
15
+ * The persisted {@link Notification} is born with `d: true` and `NO_TRY` channel states (set by
16
+ * {@link createNotificationDocumentPair}), so it is invisible to the send loop and is archived to
17
+ * {@link NotificationLoggedEventDay} during cleanup.
18
+ *
19
+ * @param input - logged-event template input parameters
20
+ * @returns the configured logged-event notification template
21
+ * @throws {Error} When `notificationModel` is not provided.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const template = createNotificationLoggedEventTemplate({
26
+ * type: 'workerClockedIn',
27
+ * notificationModel: 'project/abc123',
28
+ * data: { workerId: 'w_001', at: new Date().toISOString() }
29
+ * });
30
+ * ```
31
+ * @__NO_SIDE_EFFECTS__
32
+ */
33
+ export declare function createNotificationLoggedEventTemplate(input: CreateNotificationLoggedEventTemplateInput): CreateNotificationLoggedEventTemplate;
@@ -41,5 +41,6 @@ export interface CreateNotificationTaskTemplateInput extends Omit<CreateNotifica
41
41
  * data: { reportType: 'monthly' }
42
42
  * });
43
43
  * ```
44
+ * @__NO_SIDE_EFFECTS__
44
45
  */
45
46
  export declare function createNotificationTaskTemplate(input: CreateNotificationTaskTemplateInput): CreateNotificationTaskTemplate;
@@ -21,7 +21,7 @@ import { type NotificationBoxSendExclusionList, type NotificationBoxId } from '.
21
21
  import { type NotificationBoxRecipient, type NotificationRecipientWithConfig, type NotificationUserNotificationBoxRecipientConfig, type NotificationUserDefaultNotificationBoxRecipientConfig } from './notification.config';
22
22
  import { type YearWeekCode } from '@dereekb/date';
23
23
  import { type UserRelatedById, type UserRelated } from '../user';
24
- import { AbstractFirestoreDocument, AbstractFirestoreDocumentWithParent, type CollectionGroup, type CollectionReference, type FirestoreCollection, type FirestoreCollectionGroup, type FirestoreCollectionWithParent, type FirestoreContext, type FirestoreModelKey, type SavedToFirestoreIfTrue, type SavedToFirestoreIfFalse } from '../../common';
24
+ import { AbstractFirestoreDocument, AbstractFirestoreDocumentWithParent, type CollectionGroup, type CollectionReference, type FirestoreCollection, type FirestoreCollectionGroup, type FirestoreCollectionWithParent, type FirestoreContext, type FirestoreModelKey, type SavedToFirestoreIfTrue, type SavedToFirestoreIfFalse, type PagedItemConverter, type PagedItemFirestoreCollection, type PagedItemPageData } from '../../common';
25
25
  import { type NotificationItem } from './notification.item';
26
26
  /**
27
27
  * Abstract class providing access to all notification-related Firestore collections.
@@ -41,11 +41,15 @@ export declare abstract class NotificationFirestoreCollections {
41
41
  abstract readonly notificationCollectionGroup: NotificationFirestoreCollectionGroup;
42
42
  abstract readonly notificationWeekCollectionFactory: NotificationWeekFirestoreCollectionFactory;
43
43
  abstract readonly notificationWeekCollectionGroup: NotificationWeekFirestoreCollectionGroup;
44
+ abstract readonly notificationLoggedEventDayCollectionFactory: NotificationLoggedEventDayFirestoreCollectionFactory;
45
+ abstract readonly notificationLoggedEventDayCollectionGroup: NotificationLoggedEventDayFirestoreCollectionGroup;
46
+ abstract readonly notificationLoggedEventDayPagedItemsCollectionFactory: NotificationLoggedEventDayPagedItemsFirestoreCollectionFactory;
47
+ abstract readonly notificationLoggedEventDayPageCollectionGroup: NotificationLoggedEventDayPageFirestoreCollectionGroup;
44
48
  }
45
49
  /**
46
50
  * Union of all notification model identity types, used for type-safe identity discrimination.
47
51
  */
48
- export type NotificationTypes = typeof notificationUserIdentity | typeof notificationSummaryIdentity | typeof notificationBoxIdentity | typeof notificationIdentity | typeof notificationWeekIdentity;
52
+ export type NotificationTypes = typeof notificationUserIdentity | typeof notificationSummaryIdentity | typeof notificationBoxIdentity | typeof notificationIdentity | typeof notificationWeekIdentity | typeof notificationLoggedEventDayIdentity | typeof notificationLoggedEventDayPageIdentity;
49
53
  /**
50
54
  * Notification-related model that is initialized asynchronously at a later time.
51
55
  *
@@ -376,6 +380,8 @@ export declare const notificationIdentity: import("../..").FirestoreModelIdentit
376
380
  *
377
381
  * Determines whether the box must exist, should be created on demand, or can be bypassed entirely.
378
382
  * Task-type notifications (`TASK_NOTIFICATION`) bypass the box system and run async workflows instead.
383
+ * Logged-event notifications (`LOGGED_EVENT`) are write-only records that bypass the send loop and
384
+ * are archived to {@link NotificationLoggedEventDay} during cleanup.
379
385
  */
380
386
  export declare enum NotificationSendType {
381
387
  /**
@@ -397,7 +403,15 @@ export declare enum NotificationSendType {
397
403
  *
398
404
  * This is used with Task-type notifications.
399
405
  */
400
- TASK_NOTIFICATION = 3
406
+ TASK_NOTIFICATION = 3,
407
+ /**
408
+ * A write-only logged event notification.
409
+ *
410
+ * Persisted with `d=true` and `NO_TRY` channel states from creation, so the send loop never visits it.
411
+ * Cleanup archives the notification item into {@link NotificationLoggedEventDay} (a paged, day-keyed
412
+ * subcollection of {@link NotificationBox}) instead of {@link NotificationWeek}, then deletes the source.
413
+ */
414
+ LOGGED_EVENT = 4
401
415
  }
402
416
  /**
403
417
  * Lifecycle state of a notification delivery channel (text, email, push, or summary).
@@ -662,6 +676,7 @@ export declare const notificationConverter: import("../..").SnapshotConverterFun
662
676
  *
663
677
  * @param context - Firestore context to create subcollection references from
664
678
  * @returns a factory function that creates collection references for a given NotificationBox parent
679
+ * @__NO_SIDE_EFFECTS__
665
680
  */
666
681
  export declare function notificationCollectionReferenceFactory(context: FirestoreContext): (notificationBox: NotificationBoxDocument) => CollectionReference<Notification>;
667
682
  /**
@@ -677,6 +692,7 @@ export type NotificationFirestoreCollectionFactory = (parent: NotificationBoxDoc
677
692
  *
678
693
  * @param firestoreContext - Firestore context to bind the collection factory to
679
694
  * @returns a factory that creates typed Firestore subcollections for Notification documents
695
+ * @__NO_SIDE_EFFECTS__
680
696
  */
681
697
  export declare function notificationFirestoreCollectionFactory(firestoreContext: FirestoreContext): NotificationFirestoreCollectionFactory;
682
698
  /**
@@ -742,6 +758,7 @@ export declare const notificationWeekConverter: import("../..").SnapshotConverte
742
758
  *
743
759
  * @param context - Firestore context to create subcollection references from
744
760
  * @returns a factory function that creates collection references for a given NotificationBox parent
761
+ * @__NO_SIDE_EFFECTS__
745
762
  */
746
763
  export declare function notificationWeekCollectionReferenceFactory(context: FirestoreContext): (notificationBox: NotificationBoxDocument) => CollectionReference<NotificationWeek>;
747
764
  /**
@@ -757,6 +774,7 @@ export type NotificationWeekFirestoreCollectionFactory = (parent: NotificationBo
757
774
  *
758
775
  * @param firestoreContext - Firestore context to bind the collection factory to
759
776
  * @returns a factory that creates typed Firestore subcollections for NotificationWeek documents
777
+ * @__NO_SIDE_EFFECTS__
760
778
  */
761
779
  export declare function notificationWeekFirestoreCollectionFactory(firestoreContext: FirestoreContext): NotificationWeekFirestoreCollectionFactory;
762
780
  /**
@@ -777,3 +795,161 @@ export type NotificationWeekFirestoreCollectionGroup = FirestoreCollectionGroup<
777
795
  * @returns a typed Firestore collection group for querying NotificationWeek documents across all parents
778
796
  */
779
797
  export declare function notificationWeekFirestoreCollectionGroup(firestoreContext: FirestoreContext): NotificationWeekFirestoreCollectionGroup;
798
+ /**
799
+ * Identity for {@link NotificationLoggedEventDay} wrapper documents. Subcollection of {@link NotificationBox}.
800
+ * Collection name: `'notificationLoggedEventDay'`, short code: `'nbnle'`.
801
+ *
802
+ * Each wrapper document is keyed by an ISO 8601 day string (e.g. `'2026-05-08'`) and exists primarily
803
+ * as the parent of a per-day paged items subcollection (see {@link notificationLoggedEventDayPageIdentity}).
804
+ */
805
+ export declare const notificationLoggedEventDayIdentity: import("../..").FirestoreModelIdentityWithParent<import("../..").RootFirestoreModelIdentity<"notificationBox", "nb">, "notificationLoggedEventDay", "nbnle">;
806
+ /**
807
+ * Identity for the page documents inside a {@link NotificationLoggedEventDay}'s paged items subcollection.
808
+ * Collection name: `'notificationLoggedEventDayPage'`, short code: `'nbnlep'`.
809
+ *
810
+ * The framework manages page IDs (`'_index'`, `'0'`, `'1'`, ...) — consumers interact with the paged
811
+ * collection accessor and do not address page docs directly.
812
+ */
813
+ export declare const notificationLoggedEventDayPageIdentity: import("../..").FirestoreModelIdentityWithParent<import("../..").FirestoreModelIdentityWithParent<import("../..").RootFirestoreModelIdentity<"notificationBox", "nb">, "notificationLoggedEventDay", "nbnle">, "notificationLoggedEventDayPage", "nbnlep">;
814
+ /**
815
+ * Per-item converter applied to {@link NotificationItem} entries when reading/writing logged-event
816
+ * day pages. Wraps the existing {@link firestoreNotificationItem} sub-object converter so individual
817
+ * items round-trip through the same field rules used everywhere else NotificationItems are persisted.
818
+ */
819
+ export declare const notificationLoggedEventDayItemConverter: PagedItemConverter<NotificationItem>;
820
+ /**
821
+ * Day-keyed wrapper document for a single day's worth of archived logged-event notifications under a
822
+ * {@link NotificationBox}.
823
+ *
824
+ * The document ID is an ISO 8601 day string (e.g. `'2026-05-08'`). The wrapper itself stores only the
825
+ * day code redundantly in {@link d}; the actual {@link NotificationItem} entries live in the day's
826
+ * paged subcollection (see {@link notificationLoggedEventDayPagedItemsCollectionFactory}). The split
827
+ * keeps each day's archive bounded — no single document can exceed the 1MB Firestore cap because
828
+ * items are distributed across pages by {@link makePagedItemFirestoreCollection}.
829
+ *
830
+ * @dbxModel
831
+ */
832
+ export interface NotificationLoggedEventDay {
833
+ /**
834
+ * ISO 8601 day string identifying this day. Matches the document ID.
835
+ *
836
+ * @dbxModelVariable day
837
+ */
838
+ readonly d: string;
839
+ }
840
+ export type NotificationLoggedEventDayRoles = GrantedReadRole;
841
+ export declare class NotificationLoggedEventDayDocument extends AbstractFirestoreDocumentWithParent<NotificationBox, NotificationLoggedEventDay, NotificationLoggedEventDayDocument, typeof notificationLoggedEventDayIdentity> {
842
+ get modelIdentity(): import("../..").FirestoreModelIdentityWithParent<import("../..").RootFirestoreModelIdentity<"notificationBox", "nb">, "notificationLoggedEventDay", "nbnle">;
843
+ }
844
+ /**
845
+ * Firestore snapshot converter for {@link NotificationLoggedEventDay} wrapper documents.
846
+ */
847
+ export declare const notificationLoggedEventDayConverter: import("../..").SnapshotConverterFunctions<NotificationLoggedEventDay, Partial<import("@dereekb/util").ReplaceType<NotificationLoggedEventDay, import("@dereekb/util").MaybeMap<object>, any>>>;
848
+ /**
849
+ * Creates a factory that produces {@link NotificationLoggedEventDay} subcollection references for a given {@link NotificationBoxDocument} parent.
850
+ *
851
+ * @param context - Firestore context to create subcollection references from
852
+ * @returns a factory function that creates collection references for a given NotificationBox parent
853
+ * @__NO_SIDE_EFFECTS__
854
+ */
855
+ export declare function notificationLoggedEventDayCollectionReferenceFactory(context: FirestoreContext): (notificationBox: NotificationBoxDocument) => CollectionReference<NotificationLoggedEventDay>;
856
+ /**
857
+ * Typed Firestore subcollection for {@link NotificationLoggedEventDay} wrapper documents under a {@link NotificationBox} parent.
858
+ */
859
+ export type NotificationLoggedEventDayFirestoreCollection = FirestoreCollectionWithParent<NotificationLoggedEventDay, NotificationBox, NotificationLoggedEventDayDocument, NotificationBoxDocument>;
860
+ /**
861
+ * Factory function that creates a {@link NotificationLoggedEventDayFirestoreCollection} for a given {@link NotificationBoxDocument} parent.
862
+ */
863
+ export type NotificationLoggedEventDayFirestoreCollectionFactory = (parent: NotificationBoxDocument) => NotificationLoggedEventDayFirestoreCollection;
864
+ /**
865
+ * Creates a {@link NotificationLoggedEventDayFirestoreCollectionFactory} bound to the given Firestore context.
866
+ *
867
+ * @param firestoreContext - Firestore context to bind the collection factory to
868
+ * @returns a factory that creates typed Firestore subcollections for NotificationLoggedEventDay wrapper documents
869
+ * @__NO_SIDE_EFFECTS__
870
+ */
871
+ export declare function notificationLoggedEventDayFirestoreCollectionFactory(firestoreContext: FirestoreContext): NotificationLoggedEventDayFirestoreCollectionFactory;
872
+ /**
873
+ * Creates a collection group reference for querying all {@link NotificationLoggedEventDay} documents across all {@link NotificationBox} parents.
874
+ *
875
+ * @param context - Firestore context to create the collection group reference from
876
+ * @returns a typed collection group for querying NotificationLoggedEventDay documents across all parents
877
+ */
878
+ export declare function notificationLoggedEventDayCollectionReference(context: FirestoreContext): CollectionGroup<NotificationLoggedEventDay>;
879
+ /**
880
+ * Typed collection group for querying {@link NotificationLoggedEventDay} documents across all parents.
881
+ */
882
+ export type NotificationLoggedEventDayFirestoreCollectionGroup = FirestoreCollectionGroup<NotificationLoggedEventDay, NotificationLoggedEventDayDocument>;
883
+ /**
884
+ * Creates a typed {@link NotificationLoggedEventDayFirestoreCollectionGroup} bound to the given Firestore context.
885
+ *
886
+ * @param firestoreContext - Firestore context to bind the collection group to
887
+ * @returns a typed Firestore collection group for querying NotificationLoggedEventDay documents across all parents
888
+ */
889
+ export declare function notificationLoggedEventDayFirestoreCollectionGroup(firestoreContext: FirestoreContext): NotificationLoggedEventDayFirestoreCollectionGroup;
890
+ /**
891
+ * Page-document model shape for the inner paged collection. Each page stores a slice of
892
+ * {@link NotificationItem} entries in {@link PagedItemPageData.i}, plus a denormalized count.
893
+ */
894
+ export type NotificationLoggedEventDayPageDocumentData = PagedItemPageData<NotificationItem>;
895
+ /**
896
+ * {@link AbstractFirestoreDocumentWithParent} implementation for a single page document inside the
897
+ * {@link NotificationLoggedEventDayPagedItemsFirestoreCollection} of a {@link NotificationLoggedEventDayDocument}.
898
+ *
899
+ * Page docs are managed internally by the paged accessor — consumers do not address them directly.
900
+ */
901
+ export declare class NotificationLoggedEventDayPageDocument extends AbstractFirestoreDocumentWithParent<NotificationLoggedEventDay, NotificationLoggedEventDayPageDocumentData, NotificationLoggedEventDayPageDocument, typeof notificationLoggedEventDayPageIdentity> {
902
+ get modelIdentity(): import("../..").FirestoreModelIdentityWithParent<import("../..").FirestoreModelIdentityWithParent<import("../..").RootFirestoreModelIdentity<"notificationBox", "nb">, "notificationLoggedEventDay", "nbnle">, "notificationLoggedEventDayPage", "nbnlep">;
903
+ }
904
+ /**
905
+ * Creates a factory that produces page subcollection references for a given {@link NotificationLoggedEventDayDocument} parent.
906
+ *
907
+ * @param context - Firestore context to create subcollection references from
908
+ * @returns a factory function that creates collection references for a given NotificationLoggedEventDayDocument parent
909
+ * @__NO_SIDE_EFFECTS__
910
+ */
911
+ export declare function notificationLoggedEventDayPagedItemsCollectionReferenceFactory(context: FirestoreContext): (day: NotificationLoggedEventDayDocument) => CollectionReference<NotificationLoggedEventDayPageDocumentData>;
912
+ /**
913
+ * Typed paged Firestore subcollection of {@link NotificationItem} entries living under a {@link NotificationLoggedEventDayDocument}.
914
+ *
915
+ * Items are distributed across page documents by {@link makePagedItemFirestoreCollection} using the
916
+ * default count-based dynamic distribution scheme. Consumers should use the paged accessor methods
917
+ * (e.g. {@link FirestorePagedItemAccessor.loadAllItems}, {@link FirestorePagedItemAccessor.writeAllItemsInTransaction})
918
+ * rather than the inherited document accessor.
919
+ */
920
+ export type NotificationLoggedEventDayPagedItemsFirestoreCollection = PagedItemFirestoreCollection<NotificationItem, NotificationLoggedEventDay, NotificationLoggedEventDayPageDocument, NotificationLoggedEventDayDocument>;
921
+ /**
922
+ * Factory function that creates a {@link NotificationLoggedEventDayPagedItemsFirestoreCollection} for a given {@link NotificationLoggedEventDayDocument} parent.
923
+ */
924
+ export type NotificationLoggedEventDayPagedItemsFirestoreCollectionFactory = (parent: NotificationLoggedEventDayDocument) => NotificationLoggedEventDayPagedItemsFirestoreCollection;
925
+ /**
926
+ * Creates a {@link NotificationLoggedEventDayPagedItemsFirestoreCollectionFactory} bound to the given Firestore context.
927
+ *
928
+ * Uses the framework's default count-based dynamic page distribution; consumers do not need to provide
929
+ * a {@link PagedItemDistributionScheme}. The per-item converter delegates to {@link firestoreNotificationItem}.
930
+ *
931
+ * @param firestoreContext - Firestore context to bind the collection factory to
932
+ * @returns a factory that creates paged Firestore subcollections of NotificationItem for a given day
933
+ * @__NO_SIDE_EFFECTS__
934
+ */
935
+ export declare function notificationLoggedEventDayPagedItemsCollectionFactory(firestoreContext: FirestoreContext): NotificationLoggedEventDayPagedItemsFirestoreCollectionFactory;
936
+ /**
937
+ * Creates a collection group reference for querying all logged-event page documents across every {@link NotificationLoggedEventDay} parent.
938
+ *
939
+ * @param context - Firestore context to create the collection group reference from
940
+ * @returns a typed collection group for querying logged-event page documents
941
+ */
942
+ export declare function notificationLoggedEventDayPageCollectionReference(context: FirestoreContext): CollectionGroup<NotificationLoggedEventDayPageDocumentData>;
943
+ /**
944
+ * Typed collection group for querying logged-event page documents across all parents. Note that the
945
+ * `_index` doc co-resides with page docs and has a different shape; callers wanting only pages should
946
+ * filter by document ID where appropriate.
947
+ */
948
+ export type NotificationLoggedEventDayPageFirestoreCollectionGroup = FirestoreCollectionGroup<NotificationLoggedEventDayPageDocumentData, NotificationLoggedEventDayPageDocument>;
949
+ /**
950
+ * Creates a typed {@link NotificationLoggedEventDayPageFirestoreCollectionGroup} bound to the given Firestore context.
951
+ *
952
+ * @param firestoreContext - Firestore context to bind the collection group to
953
+ * @returns a typed Firestore collection group for querying logged-event page documents across all parents
954
+ */
955
+ export declare function notificationLoggedEventDayPageFirestoreCollectionGroup(firestoreContext: FirestoreContext): NotificationLoggedEventDayPageFirestoreCollectionGroup;
@@ -197,5 +197,6 @@ export declare abstract class AppNotificationTemplateTypeInfoRecordService {
197
197
  * );
198
198
  * const types = service.getTemplateTypesForNotificationModel('project/abc123');
199
199
  * ```
200
+ * @__NO_SIDE_EFFECTS__
200
201
  */
201
202
  export declare function appNotificationTemplateTypeInfoRecordService(appNotificationTemplateTypeInfoRecord: NotificationTemplateTypeInfoRecord): AppNotificationTemplateTypeInfoRecordService;
@@ -12,7 +12,7 @@
12
12
  * to be stored in top-level collections while maintaining a bidirectional link to the
13
13
  * model they represent.
14
14
  */
15
- import { type FactoryWithRequiredInput } from '@dereekb/util';
15
+ import { type FactoryWithRequiredInput, type ISO8601DayString } from '@dereekb/util';
16
16
  import { type FirestoreModelId, type FirestoreModelKey, type FlatFirestoreModelKey, twoWayFlatFirestoreModelKey, inferKeyFromTwoWayFlatFirestoreModelKey, type FirebaseAuthUserId, type RootFirestoreModelIdentity, type FirestoreModelIdInput, type FirestoreCollectionName } from '../../common';
17
17
  /**
18
18
  * Document ID for a {@link NotificationBox}. Encoded as a two-way flat key of the model it represents.
@@ -116,6 +116,28 @@ export type NotificationWeekId = FirestoreModelId;
116
116
  * Full Firestore model key path for a {@link NotificationWeek} document.
117
117
  */
118
118
  export type NotificationWeekKey = FirestoreModelKey;
119
+ /**
120
+ * Document ID for a {@link NotificationLoggedEventDay} (an {@link ISO8601DayString} like `'2026-05-08'`).
121
+ */
122
+ export type NotificationLoggedEventDayId = ISO8601DayString;
123
+ /**
124
+ * Full Firestore model key path for a {@link NotificationLoggedEventDay} document.
125
+ */
126
+ export type NotificationLoggedEventDayKey = FirestoreModelKey;
127
+ /**
128
+ * Returns the {@link NotificationLoggedEventDayId} (an ISO 8601 day string in UTC)
129
+ * for the given date. Used as the document ID when archiving logged-event notifications.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * notificationLoggedEventDayId(new Date('2026-05-08T17:30:00Z'));
134
+ * // '2026-05-08'
135
+ * ```
136
+ *
137
+ * @param date - the date to derive the day ID from
138
+ * @returns the UTC ISO day string for that date
139
+ */
140
+ export declare function notificationLoggedEventDayId(date: Date): NotificationLoggedEventDayId;
119
141
  /**
120
142
  * Document ID for a {@link Notification}.
121
143
  */