akanjs 3.0.0-alpha.0 → 3.0.0-alpha.2
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/base/symbols.ts +1 -0
- package/constant/cascadePaths.ts +79 -8
- package/document/database.ts +2 -1
- package/document/databaseRegistry.ts +2 -2
- package/document/into.ts +10 -6
- package/package.json +1 -1
- package/server/SSR_MEMORY_DIAGNOSIS.md +19 -2
- package/server/cachePolicy.ts +114 -12
- package/server/di/diLifecycle.ts +8 -10
- package/server/processMetricsCollector.ts +4 -0
- package/server/resolver/CascadeRunner.ts +201 -0
- package/server/resolver/database.resolver.ts +23 -3
- package/server/resolver/index.ts +1 -0
- package/server/resolver/service.resolver.ts +9 -25
- package/server/rscWorker.tsx +32 -4
- package/server/rscWorkerHost.ts +61 -12
- package/server/ssrFromRscRenderer.tsx +2 -2
- package/server/webRouter.ts +9 -0
- package/service/ipcTypes.ts +25 -0
- package/service/predefinedAdaptor/database.adaptor.ts +3 -3
- package/service/serve.ts +5 -1
- package/service/types.ts +2 -0
- package/types/base/symbols.d.ts +1 -0
- package/types/constant/cascadePaths.d.ts +22 -4
- package/types/document/database.d.ts +2 -1
- package/types/document/databaseRegistry.d.ts +2 -2
- package/types/document/into.d.ts +6 -5
- package/types/server/cachePolicy.d.ts +33 -2
- package/types/server/resolver/CascadeRunner.d.ts +13 -0
- package/types/server/resolver/database.resolver.d.ts +6 -2
- package/types/server/resolver/index.d.ts +1 -0
- package/types/server/resolver/service.resolver.d.ts +3 -3
- package/types/server/rscWorkerHost.d.ts +13 -0
- package/types/service/ipcTypes.d.ts +24 -0
- package/types/service/predefinedAdaptor/database.adaptor.d.ts +2 -2
- package/types/service/types.d.ts +2 -1
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import type { FieldObject } from "./fieldInfo.d.ts";
|
|
2
2
|
import type { ConstantModelRef } from "./via.d.ts";
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Which end of a relation goes away with the other. `removeRef` removes what the field points at when this
|
|
5
|
+
* document is removed; `removeWith` removes this document when what the field points at is removed. The two
|
|
6
|
+
* read identically on a relation field, so the value has to name the direction — a mistake here is a data loss.
|
|
7
|
+
*/
|
|
8
|
+
export declare const cascadeActions: readonly ["removeRef", "removeWith"];
|
|
5
9
|
export type CascadeAction = (typeof cascadeActions)[number];
|
|
10
|
+
/** How a `removeWith` field names the owner whose removal takes this document with it. */
|
|
11
|
+
export interface CascadeWithPath {
|
|
12
|
+
readonly key: string;
|
|
13
|
+
/** Set when the field is a relation. Resolved to a refName later: the owner may not be registered yet. */
|
|
14
|
+
readonly modelRef: ConstantModelRef | null;
|
|
15
|
+
/** Set when the field declares `ref`, which names the owner at declaration. */
|
|
16
|
+
readonly refName: string | null;
|
|
17
|
+
/** Set when the field declares `refPath`: the sibling field holding the owner's refName. */
|
|
18
|
+
readonly typeKey: string | null;
|
|
19
|
+
/** The refNames `typeKey` may hold. Empty unless the field is polymorphic. */
|
|
20
|
+
readonly typeValues: readonly string[];
|
|
21
|
+
}
|
|
6
22
|
export declare class CascadePaths {
|
|
7
23
|
#private;
|
|
8
|
-
/** Field key → the model its ids point at
|
|
9
|
-
readonly
|
|
24
|
+
/** Field key → the model its ids point at, removed when this document is. */
|
|
25
|
+
readonly removeRef: Map<string, ConstantModelRef>;
|
|
26
|
+
/** Field key → the owner whose removal removes this document. */
|
|
27
|
+
readonly removeWith: Map<string, CascadeWithPath>;
|
|
10
28
|
collect(fieldMap: FieldObject): this;
|
|
11
29
|
}
|
|
@@ -4,7 +4,7 @@ import type { DocumentModel, QueryOf } from "akanjs/constant";
|
|
|
4
4
|
import type { CacheAdaptor, CacheSetOptions } from "akanjs/service";
|
|
5
5
|
import type { DataLoader } from "./dataLoader.d.ts";
|
|
6
6
|
import type { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta.d.ts";
|
|
7
|
-
import type { CRUDEventType, Mdl, SaveEventType } from "./into.d.ts";
|
|
7
|
+
import type { CRUDEventType, Mdl, SaveEventType, UpdateResult } from "./into.d.ts";
|
|
8
8
|
import type { DataInputOf, FindQueryOption, ListQueryOption } from "./types.d.ts";
|
|
9
9
|
export declare class CacheDatabase<T = unknown> {
|
|
10
10
|
private readonly refName;
|
|
@@ -57,6 +57,7 @@ type DatabaseModelWithQuerySort<T extends string, Input, Doc, Obj, Insight, Quer
|
|
|
57
57
|
__create: (data: _DataInput) => Promise<Doc>;
|
|
58
58
|
__update: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
59
59
|
__remove: (id: string) => Promise<Doc>;
|
|
60
|
+
__removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
60
61
|
__list(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
|
|
61
62
|
__listIds(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
|
|
62
63
|
__find(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
|
|
@@ -8,7 +8,7 @@ export interface DatabaseModel<T extends string = string, Input = any, Doc = any
|
|
|
8
8
|
model: ModelCls<Model>;
|
|
9
9
|
filter: FilterCls<Filter>;
|
|
10
10
|
obj: ConstantCls<Obj>;
|
|
11
|
-
insight:
|
|
11
|
+
insight: DatabaseCls<Insight>;
|
|
12
12
|
_Input: Input;
|
|
13
13
|
_Doc: Doc;
|
|
14
14
|
_Model: Model;
|
|
@@ -32,6 +32,6 @@ export declare class DatabaseRegistry {
|
|
|
32
32
|
static getScalar<AllowEmpty extends boolean = false>(refName: string, { allowEmpty }?: {
|
|
33
33
|
allowEmpty?: AllowEmpty;
|
|
34
34
|
}): AllowEmpty extends true ? DatabaseCls | undefined : DatabaseCls;
|
|
35
|
-
static buildModel<T extends string, Input, Doc, Model, Obj, Insight, Filter extends FilterInstance, _Query extends ExtractQuery<Filter> = ExtractQuery<Filter>, _Sort extends ExtractSort<Filter> = ExtractSort<Filter>>(refName: T, input: DatabaseCls<Input>, doc: DatabaseCls<Doc>, model: ModelCls<Model>, obj: ConstantCls<Obj>, insight:
|
|
35
|
+
static buildModel<T extends string, Input, Doc, Model, Obj, Insight, Filter extends FilterInstance, _Query extends ExtractQuery<Filter> = ExtractQuery<Filter>, _Sort extends ExtractSort<Filter> = ExtractSort<Filter>>(refName: T, input: DatabaseCls<Input>, doc: DatabaseCls<Doc>, model: ModelCls<Model>, obj: ConstantCls<Obj>, insight: DatabaseCls<Insight>, filter: FilterCls<Filter>): DatabaseModel<T, Input, Doc, Model, Obj, Insight, Filter, _Query, _Sort>;
|
|
36
36
|
static buildScalar<T extends string, Model>(refName: T, Model: DatabaseCls<Model>): DatabaseCls<Model>;
|
|
37
37
|
}
|
package/types/document/into.d.ts
CHANGED
|
@@ -60,16 +60,17 @@ export type Mdl<Doc, Raw, _RawDoc = DocumentModel<Raw>, _RawQuery extends Docume
|
|
|
60
60
|
exists(query: _RawQuery): Promise<string | null>;
|
|
61
61
|
updateOne(query: _RawQuery, update: DocumentUpdateInput<_RawDoc>, options?: DocumentUpdateOptions): Promise<UpdateResult>;
|
|
62
62
|
updateMany(query: _RawQuery, update: DocumentUpdateInput<_RawDoc>): Promise<UpdateResult>;
|
|
63
|
-
|
|
63
|
+
removeMany(query: _RawQuery): Promise<UpdateResult>;
|
|
64
64
|
bulkWrite(operations: BulkWriteOperation<Raw, _RawDoc, _RawQuery>[]): Promise<UpdateResult>;
|
|
65
65
|
};
|
|
66
|
-
interface IntoConstantModel<T extends string, _CapitalizedRefName extends string, Raw> {
|
|
66
|
+
interface IntoConstantModel<T extends string, _CapitalizedRefName extends string, Raw, Insight> {
|
|
67
67
|
refName: T;
|
|
68
68
|
_CapitalizedRefName: _CapitalizedRefName;
|
|
69
69
|
_Full: Raw;
|
|
70
|
+
_Insight: Insight;
|
|
70
71
|
}
|
|
71
72
|
type NoInferType<T> = [T][T extends unknown ? 0 : never];
|
|
72
|
-
type IntoModelActions<T extends string, _CapitalizedRefName extends string, Doc, Raw, _Query, _Sort, _QueryOfDoc = QueryOf<Doc>> = {
|
|
73
|
+
type IntoModelActions<T extends string, _CapitalizedRefName extends string, Doc, Raw, Insight, _Query, _Sort, _QueryOfDoc = QueryOf<Doc>> = {
|
|
73
74
|
[key in _CapitalizedRefName]: Mdl<Doc, Raw>;
|
|
74
75
|
} & {
|
|
75
76
|
[key in `${Uncapitalize<_CapitalizedRefName>}Loader`]: DataLoader<string, Doc, string>;
|
|
@@ -87,6 +88,6 @@ type IntoModelActions<T extends string, _CapitalizedRefName extends string, Doc,
|
|
|
87
88
|
[K in `update${_CapitalizedRefName}`]: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
88
89
|
} & {
|
|
89
90
|
[K in `remove${_CapitalizedRefName}`]: (id: string) => Promise<Doc>;
|
|
90
|
-
} & QueryMethodPart<_Query, _Sort, Raw, Doc,
|
|
91
|
-
export declare const into: <Doc, FilterRef extends FilterCls, T extends string, Raw, AddDbModels extends ModelCls[], _CapitalizedRefName extends string, _QueryOfDoc = QueryOf<Doc>, _Query = FilterQueryOf<FilterRef>, _Sort = FilterSortOf<FilterRef>, _LoaderBuilder extends LoaderBuilder<NoInferType<Doc>> = LoaderBuilder<Doc>>(docRef: Cls<Doc>, filterRef: FilterRef, cnst: IntoConstantModel<T, _CapitalizedRefName, Raw>, loaderBuilder: _LoaderBuilder, ...addMdls: [...AddDbModels]) => ModelCls<IntoModelActions<T, _CapitalizedRefName, Doc, Raw, _Query, _Sort, _QueryOfDoc>, ReturnType<_LoaderBuilder>>;
|
|
91
|
+
} & QueryMethodPart<_Query, _Sort, Raw, Doc, DocumentModel<Insight>, unknown, unknown, _QueryOfDoc>;
|
|
92
|
+
export declare const into: <Doc, FilterRef extends FilterCls, T extends string, Raw, Insight, AddDbModels extends ModelCls[], _CapitalizedRefName extends string, _QueryOfDoc = QueryOf<Doc>, _Query = FilterQueryOf<FilterRef>, _Sort = FilterSortOf<FilterRef>, _LoaderBuilder extends LoaderBuilder<NoInferType<Doc>> = LoaderBuilder<Doc>>(docRef: Cls<Doc>, filterRef: FilterRef, cnst: IntoConstantModel<T, _CapitalizedRefName, Raw, Insight>, loaderBuilder: _LoaderBuilder, ...addMdls: [...AddDbModels]) => ModelCls<IntoModelActions<T, _CapitalizedRefName, Doc, Raw, Insight, _Query, _Sort, _QueryOfDoc>, ReturnType<_LoaderBuilder>>;
|
|
92
93
|
export {};
|
|
@@ -78,14 +78,45 @@ export declare function shouldStoreRouteCache(input: {
|
|
|
78
78
|
}): RouteCacheRenderState;
|
|
79
79
|
export declare function hasRouteCacheInvalidationScope(invalidation?: RouteCacheInvalidation): boolean;
|
|
80
80
|
export declare function shouldInvalidateRouteCacheEntry(metadata: RouteCacheMetadata, invalidation: RouteCacheInvalidation): boolean;
|
|
81
|
+
export interface LruTtlCacheOptions<T> {
|
|
82
|
+
/**
|
|
83
|
+
* Measures one entry's payload. Entry count alone says nothing about a cache whose entries span
|
|
84
|
+
* three orders of magnitude, and a byte ceiling needs a running total to enforce. The default
|
|
85
|
+
* reports 0 rather than guessing, so `byteSize` stays honest about not knowing.
|
|
86
|
+
*/
|
|
87
|
+
sizeOf?: (value: T) => number;
|
|
88
|
+
/** Total payload ceiling. 0 leaves the cache bounded only by `maxEntries`. */
|
|
89
|
+
maxBytes?: number;
|
|
90
|
+
/** An entry over this is not stored at all, rather than evicting everything else to fit it. */
|
|
91
|
+
maxEntryBytes?: number;
|
|
92
|
+
/**
|
|
93
|
+
* Cadence of the idle sweep. Without one a filled cache never shrinks: an entry is dropped only
|
|
94
|
+
* when its own key is fetched after expiry or when a write evicts it, so a pod that stops
|
|
95
|
+
* serving holds its peak forever — measured at 100 entries / 21.4 MiB still resident 310s after
|
|
96
|
+
* the last request, with a 30s TTL. 0 disables it.
|
|
97
|
+
*/
|
|
98
|
+
sweepIntervalMs?: number;
|
|
99
|
+
}
|
|
81
100
|
export declare class LruTtlCache<T> {
|
|
82
101
|
#private;
|
|
83
102
|
readonly maxEntries: number;
|
|
84
|
-
constructor(maxEntries?: number);
|
|
103
|
+
constructor(maxEntries?: number, options?: LruTtlCacheOptions<T>);
|
|
85
104
|
get size(): number;
|
|
105
|
+
get byteSize(): number;
|
|
86
106
|
get(key: string): T | null;
|
|
87
|
-
|
|
107
|
+
/** Returns whether the entry was stored; a payload over `maxEntryBytes` is rejected. */
|
|
108
|
+
set(key: string, value: T, ttlSeconds: number): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Drops every expired entry. Deliberately a full scan rather than a walk from the oldest that
|
|
111
|
+
* stops at the first live entry: insertion order is *LRU* order because `get` reinserts, and TTLs
|
|
112
|
+
* differ per entry, so expiry is not monotonic in map order and an early break would leave
|
|
113
|
+
* expired entries behind. The map is bounded by `maxEntries`, so the scan is cheap.
|
|
114
|
+
*/
|
|
115
|
+
sweepExpired(now?: number): number;
|
|
116
|
+
/** Stops the idle sweep. The cache stays usable; only the timer goes away. */
|
|
117
|
+
dispose(): void;
|
|
88
118
|
delete(key: string): boolean;
|
|
89
119
|
invalidate(predicate: (key: string, value: T) => boolean): number;
|
|
90
120
|
clear(): void;
|
|
121
|
+
static parseByteCeiling(value: string | undefined | null, fallback?: number): number;
|
|
91
122
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ConstantModel } from "akanjs/constant";
|
|
2
|
+
import { type DocumentSchema } from "akanjs/document";
|
|
3
|
+
import type { DatabaseService, ServiceCls } from "akanjs/service";
|
|
4
|
+
export declare class CascadeRunner {
|
|
5
|
+
#private;
|
|
6
|
+
register(constant: ConstantModel, schema: DocumentSchema, srvRef: ServiceCls): void;
|
|
7
|
+
/**
|
|
8
|
+
* Called once every service is live. A `_postRemove` and a `listenPost("remove")` registered during boot both
|
|
9
|
+
* count against bulk removal, so the strategy cannot be decided before the last service has initialized.
|
|
10
|
+
*/
|
|
11
|
+
seal(getService: (refName: string) => DatabaseService): void;
|
|
12
|
+
run(refName: string, doc: Record<string, unknown>): Promise<void>;
|
|
13
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { type ConstantModel } from "akanjs/constant";
|
|
2
|
-
import { type DatabaseInstance, type DatabaseModel } from "akanjs/document";
|
|
2
|
+
import { type DatabaseInstance, type DatabaseModel, DocumentSchema } from "akanjs/document";
|
|
3
3
|
import { type AdaptorCls } from "akanjs/service";
|
|
4
4
|
export declare class DatabaseResolver {
|
|
5
|
-
|
|
5
|
+
/** Returns the schema alongside the adaptor: the cascade planner reads its `remove` hooks to pick a strategy. */
|
|
6
|
+
static resolveDatabase(constant: ConstantModel, database: DatabaseModel): {
|
|
7
|
+
adaptor: AdaptorCls<DatabaseInstance>;
|
|
8
|
+
schema: DocumentSchema;
|
|
9
|
+
};
|
|
6
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type ConstantModel } from "akanjs/constant";
|
|
2
1
|
import { type DatabaseModel } from "akanjs/document";
|
|
3
|
-
import type {
|
|
2
|
+
import type { ServiceCls } from "akanjs/service";
|
|
3
|
+
import type { CascadeRunner } from "./CascadeRunner.d.ts";
|
|
4
4
|
export declare class ServiceResolver {
|
|
5
5
|
#private;
|
|
6
|
-
static resolveDatabaseService(
|
|
6
|
+
static resolveDatabaseService(database: DatabaseModel, srvRef: ServiceCls, cascade: CascadeRunner): ServiceCls;
|
|
7
7
|
}
|
|
@@ -49,6 +49,19 @@ export declare function nextRscHostPendingChunkCount(currentPendingChunks: numbe
|
|
|
49
49
|
export declare function isRscHostPendingChunkOverflow(pendingChunks: number, maxPendingChunks: number): boolean;
|
|
50
50
|
export declare function createIdempotentRscRenderCancel(onCancel: (reason?: unknown) => void): (reason?: unknown) => void;
|
|
51
51
|
export declare function createRscWorkerInvalidateCacheMessage(invalidation?: string | RouteCacheInvalidation): RscWorkerInvalidateCacheMessage;
|
|
52
|
+
/**
|
|
53
|
+
* The RSC worker samples its own process with the same `ProcessMetricsCollector.collect` its host
|
|
54
|
+
* replica uses, so its report carries `pid` / `rssBytes` / `role` / … under the identical names.
|
|
55
|
+
* `AkanServer` spreads the host's report into its own `collect({ role, ...webRouter.getMetrics() })`
|
|
56
|
+
* and `collect` spreads `extra` last (`processMetricsCollector.ts:122`) — so passing these through
|
|
57
|
+
* unprefixed silently overwrote the replica's own process fields, and the replica's RSS was reported
|
|
58
|
+
* nowhere. Rename them onto `rscWorker*`; the `rsc*` render counters, which only the worker
|
|
59
|
+
* produces, pass through untouched.
|
|
60
|
+
*
|
|
61
|
+
* XXX A new process-level field in `ProcessMetricsCollector.collect` must be added here too, or it
|
|
62
|
+
* starts shadowing the replica again.
|
|
63
|
+
*/
|
|
64
|
+
export declare function projectRscWorkerProcessMetrics(metrics: AkanMetricsReport): AkanMetricsReport;
|
|
52
65
|
export declare function createRscHostRenderStream(input: {
|
|
53
66
|
setPending: (pending: RscPending) => void;
|
|
54
67
|
deletePending: () => void;
|
|
@@ -59,6 +59,25 @@ export interface AkanMetricsReport {
|
|
|
59
59
|
rscWorkerRestartCount?: number;
|
|
60
60
|
rscWorkerRecycleCount?: number;
|
|
61
61
|
rscWorkerLastRecycleReason?: string;
|
|
62
|
+
rscWorkerReportedAt?: number;
|
|
63
|
+
rscWorkerRssBytes?: number;
|
|
64
|
+
rscWorkerHeapTotalBytes?: number;
|
|
65
|
+
rscWorkerHeapUsedBytes?: number;
|
|
66
|
+
rscWorkerExternalBytes?: number;
|
|
67
|
+
rscWorkerArrayBuffersBytes?: number;
|
|
68
|
+
rscWorkerCpuUserMicros?: number;
|
|
69
|
+
rscWorkerCpuSystemMicros?: number;
|
|
70
|
+
rscWorkerMaxRssKb?: number;
|
|
71
|
+
rscWorkerJscHeapSizeBytes?: number;
|
|
72
|
+
rscWorkerJscHeapCapacityBytes?: number;
|
|
73
|
+
/** Off-heap bytes JSC attributes to JS objects — typed-array backing stores, i.e. cached Flight chunks. */
|
|
74
|
+
rscWorkerJscExtraMemorySizeBytes?: number;
|
|
75
|
+
rscWorkerJscObjectCount?: number;
|
|
76
|
+
rscWorkerJscProtectedObjectCount?: number;
|
|
77
|
+
rscWorkerEventLoopLagMeanMs?: number;
|
|
78
|
+
rscWorkerEventLoopLagP99Ms?: number;
|
|
79
|
+
rscWorkerEventLoopLagMaxMs?: number;
|
|
80
|
+
rscWorkerGcDurationMs?: number;
|
|
62
81
|
rscPendingRenderCount?: number;
|
|
63
82
|
rscQueuedSendCount?: number;
|
|
64
83
|
rscHostPendingChunkOverflowCount?: number;
|
|
@@ -94,9 +113,13 @@ export interface AkanMetricsReport {
|
|
|
94
113
|
rscLastRenderLoadedModuleDelta?: number;
|
|
95
114
|
rscLastRenderLoadedModules?: string[];
|
|
96
115
|
rscResultCacheEntries?: number;
|
|
116
|
+
rscResultCacheBytes?: number;
|
|
117
|
+
rscPatchResultCacheEntries?: number;
|
|
118
|
+
rscPatchResultCacheBytes?: number;
|
|
97
119
|
rscResultCacheHits?: number;
|
|
98
120
|
rscResultCacheMisses?: number;
|
|
99
121
|
rscResultCacheBypass?: number;
|
|
122
|
+
/** Keys the SSR chunk registry tracks — NOT a memory bound; the modules stay in Bun's ESM registry. */
|
|
100
123
|
ssrChunkRegistrySize?: number;
|
|
101
124
|
ssrChunkLoadCount?: number;
|
|
102
125
|
ssrChunkCacheHitCount?: number;
|
|
@@ -107,6 +130,7 @@ export interface AkanMetricsReport {
|
|
|
107
130
|
httpCsrCount?: number;
|
|
108
131
|
httpImageCount?: number;
|
|
109
132
|
httpHtmlCacheEntries?: number;
|
|
133
|
+
httpHtmlCacheBytes?: number;
|
|
110
134
|
httpHtmlCacheHits?: number;
|
|
111
135
|
httpHtmlCacheMisses?: number;
|
|
112
136
|
httpHtmlCacheBypass?: number;
|
|
@@ -56,7 +56,7 @@ export interface DocumentStore {
|
|
|
56
56
|
matchedCount: number;
|
|
57
57
|
modifiedCount: number;
|
|
58
58
|
}>;
|
|
59
|
-
|
|
59
|
+
removeManyByQuery(query: DocumentQuery): Promise<{
|
|
60
60
|
acknowledged: boolean;
|
|
61
61
|
matchedCount: number;
|
|
62
62
|
modifiedCount: number;
|
|
@@ -309,7 +309,7 @@ export declare class SqlDocumentStore {
|
|
|
309
309
|
matchedCount: number;
|
|
310
310
|
modifiedCount: number;
|
|
311
311
|
}>;
|
|
312
|
-
|
|
312
|
+
removeManyByQuery(query: DocumentQuery): Promise<{
|
|
313
313
|
acknowledged: boolean;
|
|
314
314
|
matchedCount: number;
|
|
315
315
|
modifiedCount: number;
|
package/types/service/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Cls, MergeAllTypes, PromiseOrObject } from "akanjs/base";
|
|
2
2
|
import type { Logger } from "akanjs/common";
|
|
3
3
|
import type { QueryOf } from "akanjs/constant";
|
|
4
|
-
import type { CRUDEventType, DatabaseModel, DataInputOf, FilterInstance, FindQueryOption, GetDocObject, ListQueryOption, QueryMethodPart, SaveEventType } from "akanjs/document";
|
|
4
|
+
import type { CRUDEventType, DatabaseModel, DataInputOf, FilterInstance, FindQueryOption, GetDocObject, ListQueryOption, QueryMethodPart, SaveEventType, UpdateResult } from "akanjs/document";
|
|
5
5
|
type ServiceMixinOmitKey = "onInit" | "onDestroy" | "_libsOnInit" | "_libsOnDestroy" | "_preCreate" | "_postCreate" | "_preUpdate" | "_postUpdate" | "_preRemove" | "_postRemove" | "_libsPreCreate" | "_libsPostCreate" | "_libsPreUpdate" | "_libsPostUpdate" | "_libsPreRemove" | "_libsPostRemove";
|
|
6
6
|
type DatabaseQueryMethods<Query, Sort, Obj, Doc, Insight, FindQueryOption, ListQueryOption, DocQuery> = QueryMethodPart<Query, Sort, Obj, Doc, Insight, FindQueryOption, ListQueryOption, DocQuery>;
|
|
7
7
|
type DocumentLike = {
|
|
@@ -31,6 +31,7 @@ export type DatabaseService<T extends string = string, Input = any, Doc = any, O
|
|
|
31
31
|
__create: (data: _DataInputOfDoc) => Promise<Doc>;
|
|
32
32
|
__update: (id: string, data: Partial<Doc>) => Promise<Doc>;
|
|
33
33
|
__remove: (id: string) => Promise<Doc>;
|
|
34
|
+
__removeMany: (query: _QueryOfDoc) => Promise<UpdateResult>;
|
|
34
35
|
__list(query?: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
|
|
35
36
|
__listIds(query?: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
|
|
36
37
|
__find(query?: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
|