alepha 0.7.3 → 0.7.4
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/cache/redis.cjs +12 -0
- package/cache/redis.d.ts +105 -0
- package/cache/redis.js +1 -0
- package/cache.d.ts +144 -217
- package/core.d.ts +122 -127
- package/datetime.d.ts +1 -1
- package/lock/redis.cjs +50 -0
- package/lock/redis.d.ts +26 -0
- package/lock/redis.js +47 -0
- package/lock.d.ts +58 -108
- package/package.json +36 -38
- package/postgres.d.ts +15 -26
- package/queue.d.ts +109 -162
- package/react/auth.d.ts +13 -5
- package/react.d.ts +20 -58
- package/redis.d.ts +11 -5
- package/retry.d.ts +30 -30
- package/scheduler.d.ts +20 -18
- package/security.d.ts +4 -4
- package/server/cache.d.ts +5 -5
- package/server/swagger.d.ts +7 -2
- package/server.d.ts +5 -10
- package/src/cache/redis.ts +1 -0
- package/src/lock/redis.ts +1 -0
- package/src/queue/redis.ts +1 -0
- package/src/topic/redis.ts +1 -0
- package/topic.d.ts +18 -84
package/core.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ export { Static, StaticDecode, StaticEncode, TObject, TSchema, TypeGuard } from
|
|
|
5
5
|
import { TypeCheck } from '@sinclair/typebox/compiler';
|
|
6
6
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
7
7
|
import { ValueError } from '@sinclair/typebox/errors';
|
|
8
|
+
import { ReadableStream as ReadableStream$1 } from 'node:stream/web';
|
|
8
9
|
import * as TypeBoxValue from '@sinclair/typebox/value';
|
|
9
10
|
export { TypeBoxValue };
|
|
10
|
-
import { ReadableStream as ReadableStream$1 } from 'node:stream/web';
|
|
11
11
|
import { Readable } from 'node:stream';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -59,10 +59,10 @@ interface ServiceSubstitution<T extends object = any> {
|
|
|
59
59
|
*/
|
|
60
60
|
use: Service<T>;
|
|
61
61
|
/**
|
|
62
|
-
* If true
|
|
62
|
+
* If true and the service already exists, just ignore the substitution and do not throw an error.
|
|
63
63
|
* Mostly used for plugins to enforce a substitution without throwing an error.
|
|
64
64
|
*/
|
|
65
|
-
|
|
65
|
+
optional?: boolean;
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Every time you register a service, you can use this type to define it.
|
|
@@ -152,41 +152,15 @@ declare const $hook: {
|
|
|
152
152
|
[KIND]: string;
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
interface ModuleDescriptorOptions<T extends TSchema> {
|
|
156
|
-
name: string;
|
|
157
|
-
version?: string;
|
|
158
|
-
description?: string;
|
|
159
|
-
services?: ServiceEntry[] | ((args: Alepha & {
|
|
160
|
-
env: Static<T>;
|
|
161
|
-
}) => ServiceEntry[]);
|
|
162
|
-
env?: T;
|
|
163
|
-
}
|
|
164
|
-
type ModuleDescriptor<T extends TSchema = TSchema> = {
|
|
165
|
-
[KIND]: "MODULE";
|
|
166
|
-
[OPTIONS]: ModuleDescriptorOptions<T>;
|
|
167
|
-
};
|
|
168
|
-
/**
|
|
169
|
-
* This descriptor can be used to define the application metadata and services.
|
|
170
|
-
*/
|
|
171
|
-
declare const $module: <T extends TSchema>(opts: ModuleDescriptorOptions<T>) => ModuleDescriptor<T>;
|
|
172
155
|
interface Module {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
*/
|
|
176
|
-
name: string;
|
|
177
|
-
/**
|
|
178
|
-
* The version of the module.
|
|
179
|
-
*/
|
|
180
|
-
version?: string;
|
|
181
|
-
/**
|
|
182
|
-
* The description of the module.
|
|
183
|
-
*/
|
|
184
|
-
description?: string;
|
|
185
|
-
/**
|
|
186
|
-
* The services provided by the module.
|
|
187
|
-
*/
|
|
188
|
-
services?: Service[];
|
|
156
|
+
name?: string;
|
|
157
|
+
$services: (alepha: Alepha) => void | Alepha;
|
|
189
158
|
}
|
|
159
|
+
interface ModuleDefinition extends Module {
|
|
160
|
+
services: Array<Service>;
|
|
161
|
+
}
|
|
162
|
+
declare const isModule: (value: unknown) => value is Module;
|
|
163
|
+
declare const toModuleName: (name: string) => string;
|
|
190
164
|
|
|
191
165
|
/**
|
|
192
166
|
* /!\ Global variable /!\
|
|
@@ -198,7 +172,11 @@ interface Module {
|
|
|
198
172
|
declare const __alephaRef: {
|
|
199
173
|
context?: Alepha;
|
|
200
174
|
definition?: Service;
|
|
201
|
-
module?:
|
|
175
|
+
module?: ModuleDefinition;
|
|
176
|
+
$services?: {
|
|
177
|
+
module: ModuleDefinition;
|
|
178
|
+
parent: Service;
|
|
179
|
+
};
|
|
202
180
|
};
|
|
203
181
|
/**
|
|
204
182
|
* Cursor descriptor.
|
|
@@ -206,7 +184,7 @@ declare const __alephaRef: {
|
|
|
206
184
|
interface CursorDescriptor {
|
|
207
185
|
context: Alepha;
|
|
208
186
|
definition?: Service;
|
|
209
|
-
module?:
|
|
187
|
+
module?: ModuleDefinition;
|
|
210
188
|
}
|
|
211
189
|
/**
|
|
212
190
|
* Get Alepha instance and Class definition from the current context.
|
|
@@ -451,9 +429,8 @@ interface MockLoggerStore {
|
|
|
451
429
|
stack: Array<{
|
|
452
430
|
date: string;
|
|
453
431
|
level: string;
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}>;
|
|
432
|
+
message: string;
|
|
433
|
+
} & Record<string, any>>;
|
|
457
434
|
}
|
|
458
435
|
|
|
459
436
|
interface Env extends LoggerEnv {
|
|
@@ -463,7 +440,7 @@ interface Env extends LoggerEnv {
|
|
|
463
440
|
*/
|
|
464
441
|
NODE_ENV?: "dev" | "test" | "production";
|
|
465
442
|
/**
|
|
466
|
-
* Optional name of the application.
|
|
443
|
+
* Optional name of the application.
|
|
467
444
|
*/
|
|
468
445
|
APP_NAME?: string;
|
|
469
446
|
/**
|
|
@@ -541,7 +518,7 @@ interface Hooks {
|
|
|
541
518
|
* // state, env, and other properties
|
|
542
519
|
* })
|
|
543
520
|
*
|
|
544
|
-
* alepha.
|
|
521
|
+
* alepha.with(MyService);
|
|
545
522
|
*
|
|
546
523
|
* run(alepha); // trigger .start (and .stop) automatically
|
|
547
524
|
* ```
|
|
@@ -560,7 +537,7 @@ declare class Alepha {
|
|
|
560
537
|
/**
|
|
561
538
|
* List of all services + how they are provided.
|
|
562
539
|
*/
|
|
563
|
-
protected registry: Map<Service,
|
|
540
|
+
protected registry: Map<Service, ServiceDefinition>;
|
|
564
541
|
/**
|
|
565
542
|
* Flag indicating whether the App won't accept any further changes.
|
|
566
543
|
* Pass to true when #start() is called.
|
|
@@ -634,7 +611,7 @@ declare class Alepha {
|
|
|
634
611
|
*
|
|
635
612
|
* Modules are used to group services and provide a way to register them in the container.
|
|
636
613
|
*/
|
|
637
|
-
protected modules: Array<
|
|
614
|
+
protected modules: Array<ModuleDefinition>;
|
|
638
615
|
/**
|
|
639
616
|
* Node.js feature that allows to store context across asynchronous calls.
|
|
640
617
|
*
|
|
@@ -662,18 +639,19 @@ declare class Alepha {
|
|
|
662
639
|
*/
|
|
663
640
|
state<Key extends keyof State>(key: Key, value?: State[Key]): State[Key];
|
|
664
641
|
/**
|
|
665
|
-
*
|
|
642
|
+
* True when start() is called.
|
|
666
643
|
*
|
|
667
|
-
*
|
|
644
|
+
* -> No more services can be added, it's over, bye!
|
|
668
645
|
*/
|
|
669
|
-
|
|
670
|
-
from: string[];
|
|
671
|
-
as?: string;
|
|
672
|
-
}>;
|
|
646
|
+
isLocked(): boolean;
|
|
673
647
|
/**
|
|
674
|
-
*
|
|
648
|
+
* Returns whether the App is configured.
|
|
649
|
+
*
|
|
650
|
+
* It means that Alepha#configure() has been called.
|
|
651
|
+
*
|
|
652
|
+
* > By default, configure() is called automatically when start() is called, but you can also call it manually.
|
|
675
653
|
*/
|
|
676
|
-
|
|
654
|
+
isConfigured(): boolean;
|
|
677
655
|
/**
|
|
678
656
|
* Returns whether the App has started.
|
|
679
657
|
*
|
|
@@ -685,19 +663,9 @@ declare class Alepha {
|
|
|
685
663
|
*/
|
|
686
664
|
isReady(): boolean;
|
|
687
665
|
/**
|
|
688
|
-
* True
|
|
689
|
-
*
|
|
690
|
-
* -> No more services can be added, it's over, bye!
|
|
691
|
-
*/
|
|
692
|
-
isLocked(): boolean;
|
|
693
|
-
/**
|
|
694
|
-
* Returns whether the App is configured.
|
|
695
|
-
*
|
|
696
|
-
* It means that Alepha#configure() has been called.
|
|
697
|
-
*
|
|
698
|
-
* > By default, configure() is called automatically when start() is called, but you can also call it manually.
|
|
666
|
+
* True if the App is running in a browser environment.
|
|
699
667
|
*/
|
|
700
|
-
|
|
668
|
+
isBrowser(): boolean;
|
|
701
669
|
/**
|
|
702
670
|
* Returns whether the App is running in a serverless environment.
|
|
703
671
|
*
|
|
@@ -716,12 +684,6 @@ declare class Alepha {
|
|
|
716
684
|
* > This is automatically set by Vite or Vercel. However, you have to set it manually when running Docker apps.
|
|
717
685
|
*/
|
|
718
686
|
isProduction(): boolean;
|
|
719
|
-
/**
|
|
720
|
-
* Trigger configuration of the App manually.
|
|
721
|
-
*
|
|
722
|
-
* > configure() is called automatically when start() is called, you should not need to call it manually.
|
|
723
|
-
*/
|
|
724
|
-
configure(): Promise<this | undefined>;
|
|
725
687
|
/**
|
|
726
688
|
* Starts the App.
|
|
727
689
|
*
|
|
@@ -766,10 +728,12 @@ declare class Alepha {
|
|
|
766
728
|
/**
|
|
767
729
|
* Registers the specified service in the container.
|
|
768
730
|
*
|
|
769
|
-
* - If the service is
|
|
770
|
-
* - If the service is
|
|
731
|
+
* - If the service is ALREADY registered, the method does nothing.
|
|
732
|
+
* - If the service is NOT registered, a new instance is created and registered.
|
|
771
733
|
*
|
|
772
|
-
*
|
|
734
|
+
* Method is chainable, so you can register multiple services in a single call.
|
|
735
|
+
*
|
|
736
|
+
* > ServiceEntry allows to provide a service **substitution** feature.
|
|
773
737
|
*
|
|
774
738
|
* @example
|
|
775
739
|
* ```ts
|
|
@@ -777,34 +741,28 @@ declare class Alepha {
|
|
|
777
741
|
* class B { value = "b"; }
|
|
778
742
|
* class M { a = $inject(A); }
|
|
779
743
|
*
|
|
780
|
-
* Alepha.create().
|
|
744
|
+
* Alepha.create().with({ provide: A, use: B }).get(M).a.value; // "b"
|
|
781
745
|
* ```
|
|
782
746
|
*
|
|
783
|
-
* > Substitution is an advanced feature that allows you to replace a service with another service.
|
|
747
|
+
* > **Substitution** is an advanced feature that allows you to replace a service with another service.
|
|
784
748
|
* > It's useful for testing or for providing different implementations of a service.
|
|
749
|
+
* > If you are interested in configuring a service, use Alepha#configure() instead.
|
|
785
750
|
*
|
|
786
751
|
* @param entry - The service to register in the container.
|
|
787
752
|
* @return Current instance of Alepha.
|
|
788
753
|
*/
|
|
789
|
-
|
|
754
|
+
with<T extends object>(entry: ServiceEntry<T>): this;
|
|
790
755
|
/**
|
|
791
|
-
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
|
|
795
|
-
with: (...entries: Array<ServiceEntry | ModuleDescriptor>) => this;
|
|
796
|
-
/**
|
|
797
|
-
* Works like 'Alepha#register' but it will return the instance.
|
|
756
|
+
* Get the instance of the specified service and apply some changes, depending on the options.
|
|
757
|
+
* - If the service is already registered, it will return the existing instance. (except if `skipCache` is true)
|
|
758
|
+
* - If the service is not registered, it will create a new instance and register it. (except if `skipRegistration` is true)
|
|
759
|
+
* - New instance can be created with custom constructor arguments. (`args` option)
|
|
798
760
|
*
|
|
799
761
|
* > This method is used by $inject() under the hood.
|
|
800
762
|
*
|
|
801
763
|
* @return The instance of the specified class or type.
|
|
802
764
|
*/
|
|
803
765
|
get<T extends object>(serviceEntry: ServiceEntry<T>, opts?: {
|
|
804
|
-
/**
|
|
805
|
-
* Parent service that requested the instance.
|
|
806
|
-
*/
|
|
807
|
-
parent?: Service | null;
|
|
808
766
|
/**
|
|
809
767
|
* Ignore current existing instance.
|
|
810
768
|
*/
|
|
@@ -816,8 +774,36 @@ declare class Alepha {
|
|
|
816
774
|
/**
|
|
817
775
|
* Constructor arguments to pass when creating a new instance.
|
|
818
776
|
*/
|
|
819
|
-
args?:
|
|
777
|
+
args?: ConstructorParameters<InstantiableService<T>>;
|
|
778
|
+
/**
|
|
779
|
+
* Parent service that requested the instance.
|
|
780
|
+
* @internal
|
|
781
|
+
*/
|
|
782
|
+
parent?: Service | null;
|
|
783
|
+
/**
|
|
784
|
+
* If the service is provided by a module, the module definition.
|
|
785
|
+
* @internal
|
|
786
|
+
*/
|
|
787
|
+
module?: ModuleDefinition;
|
|
820
788
|
}): T;
|
|
789
|
+
/**
|
|
790
|
+
* Configures the specified service with the provided state.
|
|
791
|
+
* If service is not registered, it will do nothing.
|
|
792
|
+
*
|
|
793
|
+
* It's recommended to use this method on the `configure` hook.
|
|
794
|
+
* @example
|
|
795
|
+
* ```ts
|
|
796
|
+
* class AppConfig {
|
|
797
|
+
* configure = $hook({
|
|
798
|
+
* name: "configure",
|
|
799
|
+
* handler: (a) => {
|
|
800
|
+
* a.configure(MyProvider, { some: "data" });
|
|
801
|
+
* }
|
|
802
|
+
* })
|
|
803
|
+
* }
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
configure<T extends object>(service: Service<T>, state: Partial<T>): void;
|
|
821
807
|
/**
|
|
822
808
|
* Registers a hook for the specified event.
|
|
823
809
|
*/
|
|
@@ -888,11 +874,15 @@ declare class Alepha {
|
|
|
888
874
|
*/
|
|
889
875
|
parseEnv<T extends TObject>(schema: T): Static<T>;
|
|
890
876
|
/**
|
|
891
|
-
*
|
|
877
|
+
* Dump the current dependency graph of the App.
|
|
892
878
|
*
|
|
893
|
-
*
|
|
879
|
+
* This method returns a record where the keys are the names of the services.
|
|
894
880
|
*/
|
|
895
|
-
|
|
881
|
+
graph(): Record<string, {
|
|
882
|
+
from: string[];
|
|
883
|
+
as?: string;
|
|
884
|
+
module?: string;
|
|
885
|
+
}>;
|
|
896
886
|
/**
|
|
897
887
|
* @internal
|
|
898
888
|
*/
|
|
@@ -900,16 +890,20 @@ declare class Alepha {
|
|
|
900
890
|
/**
|
|
901
891
|
* @internal
|
|
902
892
|
*/
|
|
903
|
-
protected new<T extends object>(definition: Service<T>, args?: any[]): T;
|
|
893
|
+
protected new<T extends object>(definition: Service<T>, args?: any[], module?: ModuleDefinition): T;
|
|
894
|
+
/**
|
|
895
|
+
* @internal
|
|
896
|
+
*/
|
|
897
|
+
protected createLogger(env: Env): Logger;
|
|
904
898
|
/**
|
|
905
|
-
* @
|
|
899
|
+
* @internal
|
|
906
900
|
*/
|
|
907
|
-
|
|
901
|
+
getModuleOf(service: Service): Module | undefined;
|
|
908
902
|
}
|
|
909
903
|
/**
|
|
910
904
|
* This is how we store services in the Alepha container.
|
|
911
905
|
*/
|
|
912
|
-
interface
|
|
906
|
+
interface ServiceDefinition<T extends object = any> {
|
|
913
907
|
/**
|
|
914
908
|
* The class or type definition to provide.
|
|
915
909
|
*/
|
|
@@ -927,6 +921,31 @@ interface Definition<T extends object = any> {
|
|
|
927
921
|
* List of classes which use this class.
|
|
928
922
|
*/
|
|
929
923
|
parents: Array<Service | null>;
|
|
924
|
+
/**
|
|
925
|
+
* If the service is provided by a module, the module definition.
|
|
926
|
+
*/
|
|
927
|
+
module?: ModuleDefinition;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
interface RunOptions {
|
|
931
|
+
/**
|
|
932
|
+
* Environment variables to be used by the application.
|
|
933
|
+
* If not provided, it will use the current process environment.
|
|
934
|
+
*/
|
|
935
|
+
env?: Env;
|
|
936
|
+
/**
|
|
937
|
+
* A callback that will be executed before the application starts.
|
|
938
|
+
*/
|
|
939
|
+
configure?: (alepha: Alepha) => Async<void>;
|
|
940
|
+
/**
|
|
941
|
+
* A callback that will be executed once the application is ready.
|
|
942
|
+
* This is useful for initializing resources or starting background tasks.
|
|
943
|
+
*/
|
|
944
|
+
ready?: (alepha: Alepha) => Async<void>;
|
|
945
|
+
/**
|
|
946
|
+
* If true, the application will stop after the ready callback is executed.
|
|
947
|
+
*/
|
|
948
|
+
once?: boolean;
|
|
930
949
|
}
|
|
931
950
|
|
|
932
951
|
/**
|
|
@@ -973,6 +992,12 @@ declare const $env: typeof $inject;
|
|
|
973
992
|
*/
|
|
974
993
|
declare const $logger: (name?: string) => Logger;
|
|
975
994
|
|
|
995
|
+
/**
|
|
996
|
+
* Default error class for Alepha.
|
|
997
|
+
*/
|
|
998
|
+
declare class AlephaError extends Error {
|
|
999
|
+
}
|
|
1000
|
+
|
|
976
1001
|
declare class AppNotStartedError extends Error {
|
|
977
1002
|
constructor();
|
|
978
1003
|
}
|
|
@@ -1231,36 +1256,6 @@ interface AlephaStringOptions extends StringOptions {
|
|
|
1231
1256
|
declare const t: TypeProvider;
|
|
1232
1257
|
declare const isUUID: (value: string) => boolean;
|
|
1233
1258
|
|
|
1234
|
-
declare const substitute: <T extends object>(rule: {
|
|
1235
|
-
provide: T;
|
|
1236
|
-
use: T;
|
|
1237
|
-
default?: boolean;
|
|
1238
|
-
}) => {
|
|
1239
|
-
use: T;
|
|
1240
|
-
provide: T;
|
|
1241
|
-
default?: boolean;
|
|
1242
|
-
};
|
|
1243
|
-
interface RunOptions {
|
|
1244
|
-
/**
|
|
1245
|
-
* Environment variables to be used by the application.
|
|
1246
|
-
* If not provided, it will use the current process environment.
|
|
1247
|
-
*/
|
|
1248
|
-
env?: Env;
|
|
1249
|
-
/**
|
|
1250
|
-
* A callback that will be executed before the application starts.
|
|
1251
|
-
*/
|
|
1252
|
-
configure?: (alepha: Alepha) => Async<void>;
|
|
1253
|
-
/**
|
|
1254
|
-
* A callback that will be executed once the application is ready.
|
|
1255
|
-
* This is useful for initializing resources or starting background tasks.
|
|
1256
|
-
*/
|
|
1257
|
-
ready?: (alepha: Alepha) => Async<void>;
|
|
1258
|
-
/**
|
|
1259
|
-
* If true, the application will stop after the ready callback is executed.
|
|
1260
|
-
*/
|
|
1261
|
-
once?: boolean;
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
1259
|
declare const run: (entry: Alepha | Service | Array<Service>, opts?: RunOptions) => Alepha;
|
|
1265
1260
|
|
|
1266
|
-
export { $cursor, $env, $hook, $inject, $logger,
|
|
1261
|
+
export { $cursor, $env, $hook, $inject, $logger, type AbstractService, Alepha, AlephaError, type AlephaStringOptions, AppNotStartedError, type Async, type AsyncFn, type AsyncLocalStorageData, AsyncLocalStorageProvider, COLORS, CircularDependencyError, ContainerLockedError, type CursorDescriptor, type Descriptor, type DescriptorIdentifier, type DescriptorItem, type Env, type FileLike, type Hook, type HookDescriptor, type HookOptions, type Hooks, type InstantiableService, KIND, LEVEL_COLORS, type LogLevel, Logger, type LoggerEnv, type LoggerOptions, type MaybePromise, MockLogger, type MockLoggerStore, type Module, type ModuleDefinition, NotImplementedError, OPTIONS, type PromiseFn, type Service, type ServiceEntry, type ServiceSubstitution, type State, type StreamLike, type TFile, type TStream, type TextLength, TypeBoxError, TypeProvider, __alephaRef, __bind, __descriptor, descriptorEvents, isDescriptorValue, isFileLike, isModule, isTypeFile, isTypeStream, isUUID, run, t, toModuleName };
|
package/datetime.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _alepha_core from '@alepha/core';
|
|
2
2
|
import { Async } from '@alepha/core';
|
|
3
3
|
import dayjs, { ManipulateType, Dayjs } from 'dayjs';
|
|
4
|
-
import dayjsDuration from 'dayjs/plugin/duration';
|
|
4
|
+
import dayjsDuration from 'dayjs/plugin/duration.js';
|
|
5
5
|
|
|
6
6
|
declare class Interval {
|
|
7
7
|
private timer;
|
package/lock/redis.cjs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lock = require('@alepha/lock');
|
|
4
|
+
var topicRedis = require('@alepha/topic-redis');
|
|
5
|
+
var core = require('@alepha/core');
|
|
6
|
+
var redis = require('@alepha/redis');
|
|
7
|
+
|
|
8
|
+
class RedisLockProvider {
|
|
9
|
+
log = core.$logger();
|
|
10
|
+
redisProvider = core.$inject(redis.RedisProvider);
|
|
11
|
+
async set(key, value, nx, px) {
|
|
12
|
+
const options = {
|
|
13
|
+
GET: true
|
|
14
|
+
// all the secrets of $lock is based on this
|
|
15
|
+
};
|
|
16
|
+
if (px) {
|
|
17
|
+
options.expiration = {
|
|
18
|
+
type: "PX",
|
|
19
|
+
value: px
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (nx) {
|
|
23
|
+
options.condition = "NX";
|
|
24
|
+
}
|
|
25
|
+
const resp = await this.redisProvider.set(key, value, options);
|
|
26
|
+
if (resp === null) {
|
|
27
|
+
this.log.debug(`Lock already exists`, { key, value });
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
return resp.toString("utf-8");
|
|
31
|
+
}
|
|
32
|
+
async del(...keys) {
|
|
33
|
+
await this.redisProvider.del(keys);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
class AlephaLock {
|
|
37
|
+
name = "alepha.lock.redis";
|
|
38
|
+
$services = (alepha) => alepha.with({
|
|
39
|
+
provide: lock.LockTopicProvider,
|
|
40
|
+
use: topicRedis.RedisTopicProvider,
|
|
41
|
+
optional: true
|
|
42
|
+
}).with({
|
|
43
|
+
provide: lock.LockProvider,
|
|
44
|
+
use: RedisLockProvider,
|
|
45
|
+
optional: true
|
|
46
|
+
}).with(AlephaLock);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
exports.AlephaLock = AlephaLock;
|
|
50
|
+
exports.RedisLockProvider = RedisLockProvider;
|
package/lock/redis.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as _alepha_core from '@alepha/core';
|
|
2
|
+
import { Alepha } from '@alepha/core';
|
|
3
|
+
import { LockProvider } from '@alepha/lock';
|
|
4
|
+
import { RedisProvider } from '@alepha/redis';
|
|
5
|
+
|
|
6
|
+
declare class RedisLockProvider implements LockProvider {
|
|
7
|
+
protected readonly log: _alepha_core.Logger;
|
|
8
|
+
protected readonly redisProvider: RedisProvider;
|
|
9
|
+
set(key: string, value: string, nx?: boolean, px?: number): Promise<string>;
|
|
10
|
+
del(...keys: string[]): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Alepha Lock Redis Module
|
|
15
|
+
*
|
|
16
|
+
* Plugin for Alepha that provides a locking mechanism.
|
|
17
|
+
*
|
|
18
|
+
* @see {@link RedisLockProvider}
|
|
19
|
+
* @module alepha.lock.redis
|
|
20
|
+
*/
|
|
21
|
+
declare class AlephaLock {
|
|
22
|
+
readonly name = "alepha.lock.redis";
|
|
23
|
+
readonly $services: (alepha: Alepha) => Alepha;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { AlephaLock, RedisLockProvider };
|
package/lock/redis.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { LockTopicProvider, LockProvider } from '@alepha/lock';
|
|
2
|
+
import { RedisTopicProvider } from '@alepha/topic-redis';
|
|
3
|
+
import { $logger, $inject } from '@alepha/core';
|
|
4
|
+
import { RedisProvider } from '@alepha/redis';
|
|
5
|
+
|
|
6
|
+
class RedisLockProvider {
|
|
7
|
+
log = $logger();
|
|
8
|
+
redisProvider = $inject(RedisProvider);
|
|
9
|
+
async set(key, value, nx, px) {
|
|
10
|
+
const options = {
|
|
11
|
+
GET: true
|
|
12
|
+
// all the secrets of $lock is based on this
|
|
13
|
+
};
|
|
14
|
+
if (px) {
|
|
15
|
+
options.expiration = {
|
|
16
|
+
type: "PX",
|
|
17
|
+
value: px
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (nx) {
|
|
21
|
+
options.condition = "NX";
|
|
22
|
+
}
|
|
23
|
+
const resp = await this.redisProvider.set(key, value, options);
|
|
24
|
+
if (resp === null) {
|
|
25
|
+
this.log.debug(`Lock already exists`, { key, value });
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
return resp.toString("utf-8");
|
|
29
|
+
}
|
|
30
|
+
async del(...keys) {
|
|
31
|
+
await this.redisProvider.del(keys);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
class AlephaLock {
|
|
35
|
+
name = "alepha.lock.redis";
|
|
36
|
+
$services = (alepha) => alepha.with({
|
|
37
|
+
provide: LockTopicProvider,
|
|
38
|
+
use: RedisTopicProvider,
|
|
39
|
+
optional: true
|
|
40
|
+
}).with({
|
|
41
|
+
provide: LockProvider,
|
|
42
|
+
use: RedisLockProvider,
|
|
43
|
+
optional: true
|
|
44
|
+
}).with(AlephaLock);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { AlephaLock, RedisLockProvider };
|