@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.
- package/CHANGELOG.md +12 -0
- package/_cjs/api/internal/events.cjs +2 -2
- package/_cjs/api/internal/events.cjs.map +1 -1
- package/_cjs/fileUtil.cjs +48 -0
- package/_cjs/fileUtil.cjs.map +1 -0
- package/_cjs/services/CUPS.cjs +121 -0
- package/_cjs/services/CUPS.cjs.map +1 -0
- package/_cjs/services/QueueMaker/SQLQueue.cjs +1 -1
- package/_cjs/services/QueueMaker/SQLQueue.cjs.map +1 -1
- package/_cjs/services/QueueMaker/memQueue.cjs +1 -1
- package/_cjs/services/QueueMaker/memQueue.cjs.map +1 -1
- package/_cjs/services/QueueMaker/sbqueue.cjs +1 -1
- package/_cjs/services/QueueMaker/sbqueue.cjs.map +1 -1
- package/_cjs/services/Store/Cosmos.cjs +1 -1
- package/_cjs/services/Store/Cosmos.cjs.map +1 -1
- package/_cjs/services/Store/Disk.cjs +1 -1
- package/_cjs/services/adapters/SQL/Model.cjs +500 -0
- package/_cjs/services/adapters/SQL/Model.cjs.map +1 -0
- package/_cjs/services/adapters/SQL.cjs +11 -0
- package/_cjs/services/adapters/SQL.cjs.map +1 -0
- package/_cjs/services/adapters/ServiceBus.cjs +76 -0
- package/_cjs/services/adapters/ServiceBus.cjs.map +1 -0
- package/_cjs/services/adapters/cosmos-client.cjs +18 -0
- package/_cjs/services/adapters/cosmos-client.cjs.map +1 -0
- package/_cjs/services/adapters/index.cjs +6 -0
- package/_cjs/services/adapters/index.cjs.map +1 -0
- package/_cjs/services/adapters/logger.cjs +9 -0
- package/_cjs/services/adapters/logger.cjs.map +1 -0
- package/_cjs/services/adapters/memQueue.cjs +31 -0
- package/_cjs/services/adapters/memQueue.cjs.map +1 -0
- package/_cjs/services/adapters/mongo-client.cjs +20 -0
- package/_cjs/services/adapters/mongo-client.cjs.map +1 -0
- package/_cjs/services/adapters/redis-client.cjs +83 -0
- package/_cjs/services/adapters/redis-client.cjs.map +1 -0
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +3 -3
- package/dist/fileUtil.d.ts +23 -0
- package/dist/fileUtil.d.ts.map +1 -0
- package/dist/fileUtil.js +41 -0
- package/dist/services/CUPS.d.ts +29 -0
- package/dist/services/CUPS.d.ts.map +1 -0
- package/dist/services/CUPS.js +116 -0
- package/dist/services/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/services/QueueMaker/SQLQueue.js +2 -2
- package/dist/services/QueueMaker/memQueue.d.ts +1 -1
- package/dist/services/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/services/QueueMaker/memQueue.js +2 -2
- package/dist/services/QueueMaker/sbqueue.d.ts +3 -3
- package/dist/services/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/services/QueueMaker/sbqueue.js +2 -2
- package/dist/services/Repository/ext.d.ts +11 -11
- package/dist/services/RepositoryBase.d.ts +6 -6
- package/dist/services/Store/Cosmos.d.ts.map +1 -1
- package/dist/services/Store/Cosmos.js +2 -2
- package/dist/services/Store/Disk.js +2 -2
- package/dist/services/adapters/SQL/Model.d.ts +538 -0
- package/dist/services/adapters/SQL/Model.d.ts.map +1 -0
- package/dist/services/adapters/SQL/Model.js +508 -0
- package/dist/services/adapters/SQL.d.ts +2 -0
- package/dist/services/adapters/SQL.d.ts.map +1 -0
- package/dist/services/adapters/SQL.js +2 -0
- package/dist/services/adapters/ServiceBus.d.ts +50 -0
- package/dist/services/adapters/ServiceBus.d.ts.map +1 -0
- package/dist/services/adapters/ServiceBus.js +73 -0
- package/dist/services/adapters/cosmos-client.d.ts +10 -0
- package/dist/services/adapters/cosmos-client.d.ts.map +1 -0
- package/dist/services/adapters/cosmos-client.js +8 -0
- package/dist/services/adapters/index.d.ts +2 -0
- package/dist/services/adapters/index.d.ts.map +1 -0
- package/dist/services/adapters/index.js +2 -0
- package/dist/services/adapters/logger.d.ts +8 -0
- package/dist/services/adapters/logger.d.ts.map +1 -0
- package/dist/services/adapters/logger.js +3 -0
- package/dist/services/adapters/memQueue.d.ts +34 -0
- package/dist/services/adapters/memQueue.d.ts.map +1 -0
- package/dist/services/adapters/memQueue.js +24 -0
- package/dist/services/adapters/mongo-client.d.ts +10 -0
- package/dist/services/adapters/mongo-client.d.ts.map +1 -0
- package/dist/services/adapters/mongo-client.js +12 -0
- package/dist/services/adapters/redis-client.d.ts +29 -0
- package/dist/services/adapters/redis-client.d.ts.map +1 -0
- package/dist/services/adapters/redis-client.js +93 -0
- package/package.json +128 -12
- package/src/api/internal/events.ts +2 -2
- package/src/fileUtil.ts +85 -0
- package/src/services/CUPS.ts +158 -0
- package/src/services/QueueMaker/SQLQueue.ts +1 -1
- package/src/services/QueueMaker/memQueue.ts +1 -1
- package/src/services/QueueMaker/sbqueue.ts +7 -7
- package/src/services/Store/Cosmos.ts +1 -1
- package/src/services/Store/Disk.ts +1 -1
- package/src/services/adapters/SQL/Model.ts +939 -0
- package/src/services/adapters/SQL.ts +1 -0
- package/src/services/adapters/ServiceBus.ts +140 -0
- package/src/services/adapters/cosmos-client.ts +16 -0
- package/src/services/adapters/index.ts +0 -0
- package/src/services/adapters/logger.ts +3 -0
- package/src/services/adapters/memQueue.ts +26 -0
- package/src/services/adapters/mongo-client.ts +23 -0
- package/src/services/adapters/redis-client.ts +123 -0
- package/tsconfig.src.json +0 -3
- package/src/services/Store/Redis.ts.bak +0 -88
- package/src/services/simpledb/cosmosdb.ts.bak +0 -149
- package/src/services/simpledb/diskdb.ts.bak +0 -165
- package/src/services/simpledb/index.ts.bak +0 -6
- package/src/services/simpledb/memdb.ts.bak +0 -78
- package/src/services/simpledb/mongodb.ts.bak +0 -107
- package/src/services/simpledb/redisdb.ts.bak +0 -202
- package/src/services/simpledb/shared.ts.bak +0 -117
- package/src/services/simpledb/simpledb.ts.bak +0 -121
package/src/fileUtil.ts
ADDED
|
@@ -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"
|