@effect-app/infra 2.0.2 → 2.1.1

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 (110) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/api/internal/events.cjs +2 -2
  3. package/_cjs/api/internal/events.cjs.map +1 -1
  4. package/_cjs/fileUtil.cjs +48 -0
  5. package/_cjs/fileUtil.cjs.map +1 -0
  6. package/_cjs/services/CUPS.cjs +121 -0
  7. package/_cjs/services/CUPS.cjs.map +1 -0
  8. package/_cjs/services/QueueMaker/SQLQueue.cjs +1 -1
  9. package/_cjs/services/QueueMaker/SQLQueue.cjs.map +1 -1
  10. package/_cjs/services/QueueMaker/memQueue.cjs +1 -1
  11. package/_cjs/services/QueueMaker/memQueue.cjs.map +1 -1
  12. package/_cjs/services/QueueMaker/sbqueue.cjs +1 -1
  13. package/_cjs/services/QueueMaker/sbqueue.cjs.map +1 -1
  14. package/_cjs/services/Store/Cosmos.cjs +1 -1
  15. package/_cjs/services/Store/Cosmos.cjs.map +1 -1
  16. package/_cjs/services/Store/Disk.cjs +1 -1
  17. package/_cjs/services/adapters/SQL/Model.cjs +500 -0
  18. package/_cjs/services/adapters/SQL/Model.cjs.map +1 -0
  19. package/_cjs/services/adapters/SQL.cjs +11 -0
  20. package/_cjs/services/adapters/SQL.cjs.map +1 -0
  21. package/_cjs/services/adapters/ServiceBus.cjs +76 -0
  22. package/_cjs/services/adapters/ServiceBus.cjs.map +1 -0
  23. package/_cjs/services/adapters/cosmos-client.cjs +18 -0
  24. package/_cjs/services/adapters/cosmos-client.cjs.map +1 -0
  25. package/_cjs/services/adapters/index.cjs +6 -0
  26. package/_cjs/services/adapters/index.cjs.map +1 -0
  27. package/_cjs/services/adapters/logger.cjs +9 -0
  28. package/_cjs/services/adapters/logger.cjs.map +1 -0
  29. package/_cjs/services/adapters/memQueue.cjs +31 -0
  30. package/_cjs/services/adapters/memQueue.cjs.map +1 -0
  31. package/_cjs/services/adapters/mongo-client.cjs +20 -0
  32. package/_cjs/services/adapters/mongo-client.cjs.map +1 -0
  33. package/_cjs/services/adapters/redis-client.cjs +83 -0
  34. package/_cjs/services/adapters/redis-client.cjs.map +1 -0
  35. package/dist/api/internal/events.d.ts.map +1 -1
  36. package/dist/api/internal/events.js +3 -3
  37. package/dist/fileUtil.d.ts +23 -0
  38. package/dist/fileUtil.d.ts.map +1 -0
  39. package/dist/fileUtil.js +41 -0
  40. package/dist/services/CUPS.d.ts +29 -0
  41. package/dist/services/CUPS.d.ts.map +1 -0
  42. package/dist/services/CUPS.js +116 -0
  43. package/dist/services/QueueMaker/SQLQueue.d.ts.map +1 -1
  44. package/dist/services/QueueMaker/SQLQueue.js +2 -2
  45. package/dist/services/QueueMaker/memQueue.d.ts +1 -1
  46. package/dist/services/QueueMaker/memQueue.d.ts.map +1 -1
  47. package/dist/services/QueueMaker/memQueue.js +2 -2
  48. package/dist/services/QueueMaker/sbqueue.d.ts +3 -3
  49. package/dist/services/QueueMaker/sbqueue.d.ts.map +1 -1
  50. package/dist/services/QueueMaker/sbqueue.js +2 -2
  51. package/dist/services/Repository/ext.d.ts +11 -11
  52. package/dist/services/RepositoryBase.d.ts +6 -6
  53. package/dist/services/Store/Cosmos.d.ts.map +1 -1
  54. package/dist/services/Store/Cosmos.js +2 -2
  55. package/dist/services/Store/Disk.js +2 -2
  56. package/dist/services/adapters/SQL/Model.d.ts +538 -0
  57. package/dist/services/adapters/SQL/Model.d.ts.map +1 -0
  58. package/dist/services/adapters/SQL/Model.js +508 -0
  59. package/dist/services/adapters/SQL.d.ts +2 -0
  60. package/dist/services/adapters/SQL.d.ts.map +1 -0
  61. package/dist/services/adapters/SQL.js +2 -0
  62. package/dist/services/adapters/ServiceBus.d.ts +50 -0
  63. package/dist/services/adapters/ServiceBus.d.ts.map +1 -0
  64. package/dist/services/adapters/ServiceBus.js +73 -0
  65. package/dist/services/adapters/cosmos-client.d.ts +10 -0
  66. package/dist/services/adapters/cosmos-client.d.ts.map +1 -0
  67. package/dist/services/adapters/cosmos-client.js +8 -0
  68. package/dist/services/adapters/index.d.ts +2 -0
  69. package/dist/services/adapters/index.d.ts.map +1 -0
  70. package/dist/services/adapters/index.js +2 -0
  71. package/dist/services/adapters/logger.d.ts +8 -0
  72. package/dist/services/adapters/logger.d.ts.map +1 -0
  73. package/dist/services/adapters/logger.js +3 -0
  74. package/dist/services/adapters/memQueue.d.ts +34 -0
  75. package/dist/services/adapters/memQueue.d.ts.map +1 -0
  76. package/dist/services/adapters/memQueue.js +24 -0
  77. package/dist/services/adapters/mongo-client.d.ts +10 -0
  78. package/dist/services/adapters/mongo-client.d.ts.map +1 -0
  79. package/dist/services/adapters/mongo-client.js +12 -0
  80. package/dist/services/adapters/redis-client.d.ts +29 -0
  81. package/dist/services/adapters/redis-client.d.ts.map +1 -0
  82. package/dist/services/adapters/redis-client.js +93 -0
  83. package/package.json +128 -12
  84. package/src/api/internal/events.ts +2 -2
  85. package/src/fileUtil.ts +85 -0
  86. package/src/services/CUPS.ts +158 -0
  87. package/src/services/QueueMaker/SQLQueue.ts +1 -1
  88. package/src/services/QueueMaker/memQueue.ts +1 -1
  89. package/src/services/QueueMaker/sbqueue.ts +7 -7
  90. package/src/services/Store/Cosmos.ts +1 -1
  91. package/src/services/Store/Disk.ts +1 -1
  92. package/src/services/adapters/SQL/Model.ts +939 -0
  93. package/src/services/adapters/SQL.ts +1 -0
  94. package/src/services/adapters/ServiceBus.ts +140 -0
  95. package/src/services/adapters/cosmos-client.ts +16 -0
  96. package/src/services/adapters/index.ts +0 -0
  97. package/src/services/adapters/logger.ts +3 -0
  98. package/src/services/adapters/memQueue.ts +26 -0
  99. package/src/services/adapters/mongo-client.ts +23 -0
  100. package/src/services/adapters/redis-client.ts +123 -0
  101. package/tsconfig.src.json +0 -3
  102. package/src/services/Store/Redis.ts.bak +0 -88
  103. package/src/services/simpledb/cosmosdb.ts.bak +0 -149
  104. package/src/services/simpledb/diskdb.ts.bak +0 -165
  105. package/src/services/simpledb/index.ts.bak +0 -6
  106. package/src/services/simpledb/memdb.ts.bak +0 -78
  107. package/src/services/simpledb/mongodb.ts.bak +0 -107
  108. package/src/services/simpledb/redisdb.ts.bak +0 -202
  109. package/src/services/simpledb/shared.ts.bak +0 -117
  110. package/src/services/simpledb/simpledb.ts.bak +0 -121
@@ -0,0 +1,85 @@
1
+ import crypto from "crypto"
2
+ import { Effect } from "effect-app"
3
+ import type { Abortable } from "events"
4
+ import type { Mode, ObjectEncodingOptions, OpenMode } from "fs"
5
+ import fs from "fs/promises"
6
+ import os from "os"
7
+ import path from "path"
8
+ import type internal from "stream"
9
+
10
+ export function readFile(fileName: string) {
11
+ return Effect.tryPromise(() => fs.readFile(fileName))
12
+ }
13
+
14
+ export function createReadableStream(fileName: string) {
15
+ return Effect.map(openFile(fileName), (file) => file.createReadStream())
16
+ }
17
+
18
+ export function openFile(fileName: string) {
19
+ return Effect.acquireRelease(Effect.tryPromise(() => fs.open(fileName)), (f) => Effect.promise(() => f.close()))
20
+ }
21
+
22
+ export function tempFile(
23
+ folder: string
24
+ ) {
25
+ return (prefix: string) => (data: Data, options?: FileOptions) => tempFile_(folder, prefix, data, options)
26
+ }
27
+
28
+ type Data =
29
+ | string
30
+ | NodeJS.ArrayBufferView
31
+ | Iterable<string | NodeJS.ArrayBufferView>
32
+ | AsyncIterable<string | NodeJS.ArrayBufferView>
33
+ | internal.Stream
34
+
35
+ export type FileOptions =
36
+ | (ObjectEncodingOptions & {
37
+ mode?: Mode | undefined
38
+ flag?: OpenMode | undefined
39
+ } & Abortable)
40
+ | BufferEncoding
41
+ | null
42
+ export function tempFile_(
43
+ folder: string,
44
+ prefix: string,
45
+ data: Data,
46
+ options?: FileOptions
47
+ ) {
48
+ return Effect.flatMap(
49
+ Effect
50
+ .sync(() => path.join(os.tmpdir(), folder, `${prefix}-` + crypto.randomUUID())),
51
+ (fp) =>
52
+ Effect.acquireRelease(
53
+ Effect
54
+ .map(
55
+ Effect
56
+ .tryPromise(() => fs.writeFile(fp, data, options)),
57
+ (_) => fp
58
+ ),
59
+ (p) => Effect.promise(() => fs.unlink(p))
60
+ )
61
+ )
62
+ }
63
+
64
+ /**
65
+ * Safe write file to .tmp and then rename
66
+ */
67
+ export function writeTextFile(fileName: string, content: string) {
68
+ const tmp = fileName + ".tmp"
69
+ return Effect
70
+ .andThen(
71
+ Effect
72
+ .tryPromise(() => fs.writeFile(tmp, content, "utf-8")),
73
+ Effect.tryPromise(() => fs.rename(tmp, fileName))
74
+ )
75
+ .pipe(Effect.orDie)
76
+ }
77
+
78
+ export function fileExists(fileName: string) {
79
+ return Effect.orDie(Effect
80
+ .tryPromise(() => fs.stat(fileName).then((_) => _.isFile())))
81
+ }
82
+
83
+ export function readTextFile(fileName: string) {
84
+ return Effect.tryPromise(() => fs.readFile(fileName, "utf-8"))
85
+ }
@@ -0,0 +1,158 @@
1
+ import type { FileOptions } from "@effect-app/infra/fileUtil"
2
+ import { tempFile } from "@effect-app/infra/fileUtil"
3
+ import cp from "child_process"
4
+ import { Config, Effect, Layer, Predicate } from "effect-app"
5
+ import { NonEmptyString255 } from "effect-app/Schema"
6
+ import { pretty } from "effect-app/utils"
7
+ import fs from "fs"
8
+ import os from "os"
9
+ import path from "path"
10
+ import util from "util"
11
+ import { InfraLogger } from "../logger.js"
12
+
13
+ export const PrinterId = NonEmptyString255
14
+ export type PrinterId = NonEmptyString255
15
+
16
+ const exec_ = util.promisify(cp.exec)
17
+ const exec = (command: string) =>
18
+ Effect.andThen(
19
+ InfraLogger.logDebug(`Executing: ${command}`),
20
+ Effect.tap(
21
+ Effect
22
+ .tryPromise(() => exec_(command)),
23
+ (r) => (InfraLogger.logDebug(`Executed`).pipe(Effect.annotateLogs("result", pretty(r))))
24
+ )
25
+ )
26
+
27
+ type PrinterConfig = { url?: URL | undefined; id: string }
28
+
29
+ function printFile(printer: PrinterConfig | undefined, options: string[]) {
30
+ return (filePath: string) => printFile_(filePath, printer, options)
31
+ }
32
+
33
+ function printFile_(filePath: string, printer: PrinterConfig | undefined, options: string[]) {
34
+ return exec(["lp", ...buildPrintArgs(filePath, printer, options)].join(" "))
35
+ }
36
+
37
+ function* buildPrintArgs(filePath: string, printer: PrinterConfig | undefined, options: string[]) {
38
+ if (printer) {
39
+ if (printer.url) {
40
+ yield `-h ${printer.url.host}`
41
+ if (printer.url.username) {
42
+ yield `-U ${printer.url.username}`
43
+ }
44
+ }
45
+ yield `-d "${printer.id}"`
46
+ for (const o of options) {
47
+ yield `-o ${o}`
48
+ }
49
+ }
50
+ yield `"${filePath}"`
51
+ }
52
+
53
+ export const prepareTempDir = Effect.sync(() => {
54
+ // TODO
55
+ try {
56
+ fs.mkdirSync(path.join(os.tmpdir(), "effect-ts-app"))
57
+ } catch (err) {
58
+ if (`${err}`.includes("EEXIST")) {
59
+ return
60
+ }
61
+ throw err
62
+ }
63
+ })
64
+
65
+ const makeTempFile = tempFile("effect-ts-app")
66
+ export const makePrintJobTempFile = makeTempFile("print-job")
67
+ export const makePrintJobTempFileArrayBuffer = (buffer: ArrayBuffer, options?: FileOptions) =>
68
+ makePrintJobTempFile(Buffer.from(buffer), options)
69
+
70
+ function printBuffer(printer: PrinterConfig, options: string[]) {
71
+ return (buffer: ArrayBuffer) =>
72
+ makePrintJobTempFileArrayBuffer(buffer)
73
+ .pipe(
74
+ Effect.flatMap(printFile(printer, options)),
75
+ Effect.scoped
76
+ )
77
+ }
78
+
79
+ function getAvailablePrinters(host?: string) {
80
+ return Effect.gen(function*() {
81
+ const { stdout } = yield* exec(["lpstat", ...buildListArgs({ host }), "-s"].join(" "))
82
+ return [...stdout.matchAll(/device for (\w+):/g)]
83
+ .map((_) => _[1])
84
+ .filter(Predicate.isNotNullable)
85
+ .map((_) => NonEmptyString255(_))
86
+ })
87
+ }
88
+
89
+ function* buildListArgs(config?: { host?: string | undefined }) {
90
+ if (config?.host) {
91
+ yield `-h ${config.host}`
92
+ }
93
+ }
94
+
95
+ export const CUPSConfig = Config.all({
96
+ server: Config
97
+ .string("server")
98
+ .pipe(
99
+ Config.map((s) => new URL(s)),
100
+ Config.option,
101
+ Config.nested("cups")
102
+ )
103
+ })
104
+
105
+ export class CUPS extends Effect.Service<CUPS>()("effect-app/CUPS", {
106
+ effect: Effect.gen(function*() {
107
+ const config = yield* CUPSConfig
108
+ function print(buffer: ArrayBuffer, printerId: PrinterId, ...options: string[]) {
109
+ const _print = printBuffer({
110
+ id: printerId,
111
+ url: config.server.value
112
+ }, options)
113
+ return _print(buffer)
114
+ }
115
+ return {
116
+ print,
117
+ printFile: (filePath: string, printerId: PrinterId, ...options: string[]) =>
118
+ printFile({
119
+ id: printerId,
120
+ url: config.server.value
121
+ }, options)(filePath),
122
+ getAvailablePrinters: getAvailablePrinters(config.server.value?.host)
123
+ }
124
+ })
125
+ }) {
126
+ static readonly Fake = Layer.effect(
127
+ this,
128
+ Effect.sync(() => {
129
+ return this.make({
130
+ print: (buffer, printerId, ...options) =>
131
+ InfraLogger
132
+ .logInfo("Printing to fake printer")
133
+ .pipe(
134
+ Effect.zipRight(Effect.sync(() => ({ stdout: "fake", stderr: "" }))),
135
+ Effect
136
+ .annotateLogs({
137
+ printerId,
138
+ "options": pretty(options),
139
+ "bufferSize": buffer.byteLength.toString()
140
+ })
141
+ ),
142
+ printFile: (filePath, printerId, ...options) =>
143
+ InfraLogger
144
+ .logInfo("Printing to fake printer")
145
+ .pipe(
146
+ Effect.zipRight(Effect.sync(() => ({ stdout: "fake", stderr: "" }))),
147
+ Effect
148
+ .annotateLogs({
149
+ printerId,
150
+ filePath,
151
+ "options": pretty(options)
152
+ })
153
+ ),
154
+ getAvailablePrinters: Effect.sync(() => [])
155
+ })
156
+ })
157
+ )
158
+ }
@@ -1,4 +1,3 @@
1
- import { Model } from "@effect-app/infra-adapters/SQL"
2
1
  import { getRequestContext, setupRequestContext } from "@effect-app/infra/api/setupRequest"
3
2
  import { reportNonInterruptedFailure } from "@effect-app/infra/services/QueueMaker/errors"
4
3
  import type { QueueBase } from "@effect-app/infra/services/QueueMaker/service"
@@ -10,6 +9,7 @@ import { Effect, Fiber, Option, S, Tracer } from "effect-app"
10
9
  import type { NonEmptyString255 } from "effect-app/Schema"
11
10
  import { pretty } from "effect-app/utils"
12
11
  import { InfraLogger } from "../../logger.js"
12
+ import { Model } from "../adapters/SQL.js"
13
13
 
14
14
  export const QueueId = S.Number.pipe(S.brand("QueueId"))
15
15
  export type QueueId = typeof QueueId.Type
@@ -1,9 +1,9 @@
1
- import { MemQueue } from "@effect-app/infra-adapters/memQueue"
2
1
  import { Tracer } from "effect"
3
2
  import { Effect, Fiber, flow, S } from "effect-app"
4
3
  import { pretty } from "effect-app/utils"
5
4
  import { getRequestContext, setupRequestContext } from "../../api/setupRequest.js"
6
5
  import { InfraLogger } from "../../logger.js"
6
+ import { MemQueue } from "../adapters/memQueue.js"
7
7
  import { reportNonInterruptedFailure } from "./errors.js"
8
8
  import { type QueueBase, QueueMeta } from "./service.js"
9
9
 
@@ -1,17 +1,17 @@
1
1
  import type {} from "@azure/service-bus"
2
- import {
3
- LiveSender,
4
- LiveServiceBusClient,
5
- Sender,
6
- ServiceBusReceiverFactory,
7
- subscribe
8
- } from "@effect-app/infra-adapters/ServiceBus"
9
2
  import { Tracer } from "effect"
10
3
  import { Cause, Effect, flow, Layer, S } from "effect-app"
11
4
  import type { StringId } from "effect-app/Schema"
12
5
  import { pretty } from "effect-app/utils"
13
6
  import { getRequestContext, setupRequestContext } from "../../api/setupRequest.js"
14
7
  import { InfraLogger } from "../../logger.js"
8
+ import {
9
+ LiveSender,
10
+ LiveServiceBusClient,
11
+ Sender,
12
+ ServiceBusReceiverFactory,
13
+ subscribe
14
+ } from "../adapters/ServiceBus.js"
15
15
  import { reportNonInterruptedFailure, reportNonInterruptedFailureCause, reportQueueError } from "./errors.js"
16
16
  import { type QueueBase, QueueMeta } from "./service.js"
17
17
 
@@ -1,12 +1,12 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
 
3
- import { CosmosClient, CosmosClientLayer } from "@effect-app/infra-adapters/cosmos-client"
4
3
  import { Array, Chunk, Duration, Effect, Layer, Option, pipe, Secret, Struct } from "effect-app"
5
4
  import type { NonEmptyReadonlyArray } from "effect-app"
6
5
  import { toNonEmptyArray } from "effect-app/Array"
7
6
  import { dropUndefinedT } from "effect-app/utils"
8
7
  import { OptimisticConcurrencyException } from "../../errors.js"
9
8
  import { InfraLogger } from "../../logger.js"
9
+ import { CosmosClient, CosmosClientLayer } from "../adapters/cosmos-client.js"
10
10
  import { buildWhereCosmosQuery3, logQuery } from "./Cosmos/query.js"
11
11
  import { StoreMaker } from "./service.js"
12
12
  import type { FilterArgs, PersistenceModelType, StorageConfig, Store, StoreConfig } from "./service.js"
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import * as fu from "@effect-app/infra-adapters/fileUtil"
2
+ import * as fu from "../../fileUtil.js"
3
3
 
4
4
  import fs from "fs"
5
5