@effect-native/libcrsql 0.16.301 → 4.0.0

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/README.md CHANGED
@@ -3,39 +3,99 @@
3
3
  Absolute paths to the cr-sqlite extension binaries for common desktop/server platforms, plus an optional Effect entrypoint.
4
4
 
5
5
  Supported platforms (verified on release):
6
+
6
7
  - macOS: darwin-aarch64, darwin-x86_64
7
8
  - Linux: linux-aarch64, linux-x86_64
8
9
  - Windows: win-x86_64, win-i686
9
10
 
10
11
  ## Install
11
12
 
12
- pnpm add @effect-native/libcrsql
13
+ ```sh
14
+ bun add @effect-native/libcrsql
15
+ ```
13
16
 
14
17
  ## Usage (no Effect)
15
18
 
19
+ ```ts
20
+ import { getCrSqliteExtensionPathSync, pathToCrSqliteExtension } from "@effect-native/libcrsql"
16
21
  import Database from "better-sqlite3"
17
- import { pathToCrSqliteExtension, getCrSqliteExtensionPathSync } from "@effect-native/libcrsql"
18
22
 
19
23
  const db = new Database(":memory:")
20
24
  db.loadExtension(pathToCrSqliteExtension)
21
25
  // or explicit
22
26
  // db.loadExtension(getCrSqliteExtensionPathSync("linux-x86_64"))
27
+ ```
28
+
29
+ ## Using with @effect/sql-sqlite-node
30
+
31
+ Use the Node Sqlite client from Effect and load the CR‑SQLite extension before running queries.
32
+
33
+ Simple usage (Effect):
34
+
35
+ ```ts
36
+ import { getCrSqliteExtensionPath } from "@effect-native/libcrsql/effect"
37
+ import { SqliteClient } from "@effect/sql-sqlite-node"
38
+ import { Effect, Layer } from "effect"
39
+
40
+ const SqliteBase = SqliteClient.layer({ filename: ":memory:" })
41
+
42
+ const program = Effect.gen(function*() {
43
+ const client = yield* SqliteClient.SqliteClient
44
+ const ext = yield* getCrSqliteExtensionPath
45
+ yield* client.loadExtension(ext)
46
+ const rows = yield* client`SELECT hex(crsql_site_id()) AS site_id`
47
+ console.log(rows[0].site_id)
48
+ }).pipe(Effect.provide(SqliteBase))
49
+ ```
50
+
51
+ Idiomatic Layer composition for tests:
52
+
53
+ ```ts
54
+ import { getCrSqliteExtensionPath } from "@effect-native/libcrsql/effect"
55
+ import { SqliteClient } from "@effect/sql-sqlite-node"
56
+ import { Effect, Layer } from "effect"
57
+
58
+ const SqliteBase = SqliteClient.layer({ filename: ":memory:" })
59
+
60
+ export const SqliteWithCr = Layer.effect(
61
+ SqliteClient.SqliteClient,
62
+ Effect.gen(function*() {
63
+ const client = yield* SqliteClient.SqliteClient
64
+ const ext = yield* getCrSqliteExtensionPath
65
+ yield* client.loadExtension(ext)
66
+ return client
67
+ })
68
+ ).pipe(Layer.provide(SqliteBase))
69
+
70
+ // Use in tests
71
+ // it.scoped("works", () => Effect.provide(SqliteWithCr)(...))
72
+ ```
73
+
74
+ Notes:
75
+
76
+ - better‑sqlite3 compiles with SQLite built in; you do not need @effect‑native/libsqlite for Node.
77
+ - If you need to control the SQLite binary (e.g. Bun), use @effect‑native/libsqlite and its `Database.setCustomSQLite` APIs.
23
78
 
24
79
  ## Absolute constants (no side effects)
25
80
 
81
+ ```ts
26
82
  import { linux_x86_64 } from "@effect-native/libcrsql/paths"
27
- // linux_x86_64 is an absolute string like
83
+ // linux_x86_64 is an absolute string like
28
84
  // /.../node_modules/@effect-native/libcrsql/lib/linux-x86_64/libcrsqlite.so
85
+ ```
29
86
 
30
87
  ## Effect entrypoint (optional)
31
88
 
32
- import { Effect } from "effect"
89
+ ```ts
33
90
  import { getCrSqliteExtensionPath } from "@effect-native/libcrsql/effect"
91
+ import { Effect } from "effect"
34
92
 
35
93
  const program = getCrSqliteExtensionPath()
36
94
  Effect.runPromise(program)
95
+ ```
37
96
 
38
97
  ## Notes
98
+
39
99
  - No network or postinstall scripts. Binaries are bundled in `lib/`.
40
100
  - Android and iOS are out of scope for this release.
41
101
  - Root and paths entrypoints have zero external runtime dependencies.
@@ -56,10 +116,109 @@ console.log(CRSQLITE_VERSION) // "0.16.3"
56
116
  ## Performance Note
57
117
 
58
118
  The module uses a synchronous file existence check (`fs.accessSync`) to ensure the returned path points to a real binary. This runs once per import/use and is acceptable for this package’s contract. If needed, this can be revisited later with memoization.
119
+
59
120
  ## Binary Integrity
60
121
 
61
122
  Run a local integrity check to verify bundled binaries match the expected SHA256:
62
123
 
124
+ ```sh
125
+ bun --filter @effect-native/libcrsql run verify
126
+ ```
127
+
128
+ ---
129
+
130
+ # Examples
131
+
132
+ ## nodejs + better-sqlite3
133
+
134
+ ```ts
135
+ import { pathToCrSqliteExtension } from "@effect-native/libcrsql"
136
+ import Database from "better-sqlite3"
137
+
138
+ const db = new Database(":memory:")
139
+ db.loadExtension(pathToCrSqliteExtension)
140
+
141
+ console.log("LibSqlite loaded successfully?", db.prepare("SELECT sqlite_version() AS sqlite_version").get())
142
+
143
+ console.log("CR-SQLite extension loaded successfully")
144
+ console.log("Site ID:", db.prepare("SELECT hex(crsql_site_id()) as site_id").get())
63
145
  ```
64
- pnpm --filter @effect-native/libcrsql run verify
146
+
147
+ ## bun build --compile
148
+
149
+ Embed libsqlite and crsqlite extension in a compiled Bun single file executable.
150
+
151
+ ```ts
152
+ /* eslint-disable @typescript-eslint/no-require-imports */
153
+
154
+ import { Database } from "bun:sqlite"
155
+
156
+ import { getCrSqliteExtensionPathSync } from "@effect-native/libcrsql" with { type: "macro" }
157
+ import { getLibSqlitePathSync } from "@effect-native/libsqlite" with { type: "macro" }
158
+
159
+ const embeddedLibSqlitePath = String(require(getLibSqlitePathSync()))
160
+ const embeddedCrSqliteExtensionPath = String(require(getCrSqliteExtensionPathSync()))
161
+
162
+ if (Bun.embeddedFiles.length) {
163
+ const embeddedLibSqliteFile = Bun.file(embeddedLibSqlitePath)
164
+ const exportedLibSqlitePath = `./.${embeddedLibSqliteFile.name}`
165
+ Bun.write(exportedLibSqlitePath, embeddedLibSqliteFile)
166
+ Database.setCustomSQLite(exportedLibSqlitePath)
167
+ } else {
168
+ Database.setCustomSQLite(embeddedLibSqlitePath)
169
+ }
170
+
171
+ const db = new Database(":memory:")
172
+ console.log("LibSqlite loaded successfully?", db.query("SELECT sqlite_version() AS sqlite_version").get())
173
+ db.loadExtension(embeddedCrSqliteExtensionPath, "sqlite3_crsqlite_init")
174
+
175
+ try {
176
+ } catch (cause) {
177
+ if (!String(cause).includes("no such file")) throw cause
178
+ const embeddedCrSqliteExtensionFile = Bun.file(embeddedCrSqliteExtensionPath)
179
+ const exportedCrSqliteExtensionPath = `./.${embeddedCrSqliteExtensionFile.name}`
180
+ Bun.write(exportedCrSqliteExtensionPath, embeddedCrSqliteExtensionFile)
181
+ db.loadExtension(exportedCrSqliteExtensionPath, "sqlite3_crsqlite_init")
182
+ }
183
+
184
+ console.log("CRSQLite extension loaded successfully?", db.query("SELECT hex(crsql_site_id()) AS siteId").get())
185
+ ```
186
+
187
+ ## bun build --compile
188
+
189
+ Embed libsqlite and crsqlite extension in a compiled Bun single file executable.
190
+
191
+ ```ts
192
+ /* eslint-disable @typescript-eslint/no-require-imports */
193
+ import { Database } from "bun:sqlite"
194
+
195
+ import { getCrSqliteExtensionPathSync } from "@effect-native/libcrsql" with { type: "macro" }
196
+ import { getLibSqlitePathSync } from "@effect-native/libsqlite" with { type: "macro" }
197
+
198
+ const embeddedLibSqlitePath = String(require(getLibSqlitePathSync()))
199
+ const embeddedCrSqliteExtensionPath = String(require(getCrSqliteExtensionPathSync()))
200
+
201
+ if (Bun.embeddedFiles.length) {
202
+ const embeddedLibSqliteFile = Bun.file(embeddedLibSqlitePath)
203
+ const exportedLibSqlitePath = `./.${embeddedLibSqliteFile.name}`
204
+ Bun.write(exportedLibSqlitePath, embeddedLibSqliteFile)
205
+ Database.setCustomSQLite(exportedLibSqlitePath)
206
+ } else {
207
+ Database.setCustomSQLite(embeddedLibSqlitePath)
208
+ }
209
+
210
+ const db = new Database(":memory:")
211
+ console.log("LibSqlite loaded successfully?", db.query("SELECT sqlite_version() AS sqliteVersion").get())
212
+
213
+ try {
214
+ db.loadExtension(embeddedCrSqliteExtensionPath, "sqlite3_crsqlite_init")
215
+ } catch (cause) {
216
+ if (!String(cause).includes("no such file")) throw cause
217
+ const embeddedCrSqliteExtensionFile = Bun.file(embeddedCrSqliteExtensionPath)
218
+ const exportedCrSqliteExtensionPath = `./.${embeddedCrSqliteExtensionFile.name}`
219
+ Bun.write(exportedCrSqliteExtensionPath, embeddedCrSqliteExtensionFile)
220
+ db.loadExtension(exportedCrSqliteExtensionPath, "sqlite3_crsqlite_init")
221
+ }
222
+
223
+ console.log("CRSQLite extension loaded successfully?", db.query("SELECT hex(crsql_site_id()) AS siteId").get())
65
224
  ```
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getCrSqliteExtensionPath = exports.SUPPORTED_PLATFORMS = exports.PlatformNotSupportedError = exports.ExtensionPath = exports.ExtensionNotFoundError = void 0;
7
+ var _effect = require("effect");
8
+ var fs = _interopRequireWildcard(require("node:fs"));
9
+ var _nodeUrl = require("node:url");
10
+ var _platform = require("./platform.js");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
+ /**
13
+ * Effect entrypoint: idiomatic Effect API with TaggedError failures.
14
+ *
15
+ * @since 0.16.300
16
+ */
17
+
18
+ /**
19
+ * Error indicating that a platform-arch combination is not supported.
20
+ * @since 0.16.300
21
+ */
22
+ class PlatformNotSupportedError extends /*#__PURE__*/_effect.Data.TaggedError("PlatformNotSupportedError") {
23
+ /**
24
+ * @since 0.16.300
25
+ */
26
+ get message() {
27
+ return `Platform "${this.platform}" is not supported. Detected: ${this.detectedPlatform}-${this.detectedArch}. Supported: ${this.supportedPlatforms.join(", ")}`;
28
+ }
29
+ }
30
+ /**
31
+ * Error indicating that the resolved binary path does not exist.
32
+ * @since 0.16.300
33
+ */
34
+ exports.PlatformNotSupportedError = PlatformNotSupportedError;
35
+ class ExtensionNotFoundError extends /*#__PURE__*/_effect.Data.TaggedError("ExtensionNotFoundError") {}
36
+ /**
37
+ * Brand constructor for `ExtensionPath`.
38
+ * @since 0.16.300
39
+ */
40
+ exports.ExtensionNotFoundError = ExtensionNotFoundError;
41
+ const ExtensionPath = exports.ExtensionPath = /*#__PURE__*/_effect.Brand.nominal();
42
+ // Uses a best-effort Node fs sync check without depending on @effect/platform.
43
+ /**
44
+ * Effect-based absolute path resolution with idiomatic TaggedError failures.
45
+ *
46
+ * - Succeeds with a branded `ExtensionPath` string.
47
+ * - Fails with `PlatformNotSupportedError` or `ExtensionNotFoundError`.
48
+ *
49
+ * @since 0.16.300
50
+ * @example
51
+ * import { getCrSqliteExtensionPath } from "@effect-native/libcrsql/effect"
52
+ * import { Effect } from "effect"
53
+ *
54
+ * const program = getCrSqliteExtensionPath()
55
+ * Effect.runPromise(program)
56
+ */
57
+ const getCrSqliteExtensionPath = platform => _effect.Effect.gen(function* () {
58
+ const target = platform ?? (0, _platform.detectPlatform)();
59
+ if (!(0, _platform.isSupportedPlatform)(target)) {
60
+ return yield* _effect.Effect.fail(new PlatformNotSupportedError({
61
+ platform: target,
62
+ supportedPlatforms: SUPPORTED_PLATFORMS,
63
+ detectedArch: process.arch,
64
+ detectedPlatform: process.platform
65
+ }));
66
+ }
67
+ const abs = (0, _nodeUrl.fileURLToPath)(new URL(`../${(0, _platform.buildRelativeLibraryPath)(target)}`, import.meta.url));
68
+ const exists = yield* _effect.Effect.sync(() => {
69
+ try {
70
+ // Synchronous check is acceptable here since this path is computed
71
+ // infrequently and typically only once per process.
72
+ fs.accessSync(abs);
73
+ return true;
74
+ } catch {
75
+ return false;
76
+ }
77
+ });
78
+ if (!exists) {
79
+ return yield* _effect.Effect.fail(new ExtensionNotFoundError({
80
+ path: abs,
81
+ platform: target
82
+ }));
83
+ }
84
+ return ExtensionPath(abs);
85
+ });
86
+ /**
87
+ * List of supported platforms.
88
+ * @since 0.16.300
89
+ */
90
+ exports.getCrSqliteExtensionPath = getCrSqliteExtensionPath;
91
+ const SUPPORTED_PLATFORMS = exports.SUPPORTED_PLATFORMS = _platform.SUPPORTED_PLATFORMS;
92
+ //# sourceMappingURL=effect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect.js","names":["_effect","require","fs","_interopRequireWildcard","_nodeUrl","_platform","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","PlatformNotSupportedError","Data","TaggedError","message","platform","detectedPlatform","detectedArch","supportedPlatforms","join","exports","ExtensionNotFoundError","ExtensionPath","Brand","nominal","getCrSqliteExtensionPath","Effect","gen","target","detectPlatform","isSupportedPlatform","fail","SUPPORTED_PLATFORMS","process","arch","abs","fileURLToPath","URL","buildRelativeLibraryPath","import","meta","url","exists","sync","accessSync","path","_SUPPORTED_PLATFORMS"],"sources":["../../src/effect.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Effect entrypoint: idiomatic Effect API with TaggedError failures.
3
+ *
4
+ * @since 0.16.300
5
+ */
6
+ import { Brand, Effect } from "effect";
7
+ import type { Platform as _Platform } from "./platform.js";
8
+ declare const PlatformNotSupportedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
9
+ readonly _tag: "PlatformNotSupportedError";
10
+ } & Readonly<A>;
11
+ /**
12
+ * Error indicating that a platform-arch combination is not supported.
13
+ * @since 0.16.300
14
+ */
15
+ export declare class PlatformNotSupportedError extends PlatformNotSupportedError_base<{
16
+ readonly platform: string;
17
+ readonly supportedPlatforms: ReadonlyArray<string>;
18
+ readonly detectedArch: string;
19
+ readonly detectedPlatform: string;
20
+ }> {
21
+ /**
22
+ * @since 0.16.300
23
+ */
24
+ get message(): string;
25
+ }
26
+ declare const ExtensionNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
27
+ readonly _tag: "ExtensionNotFoundError";
28
+ } & Readonly<A>;
29
+ /**
30
+ * Error indicating that the resolved binary path does not exist.
31
+ * @since 0.16.300
32
+ */
33
+ export declare class ExtensionNotFoundError extends ExtensionNotFoundError_base<{
34
+ readonly path: string;
35
+ readonly platform: string;
36
+ }> {
37
+ }
38
+ /**
39
+ * Branded absolute path to the cr-sqlite binary.
40
+ * @since 0.16.300
41
+ */
42
+ export type ExtensionPath = string & Brand.Brand<"ExtensionPath">;
43
+ /**
44
+ * Brand constructor for `ExtensionPath`.
45
+ * @since 0.16.300
46
+ */
47
+ export declare const ExtensionPath: Brand.Constructor<ExtensionPath>;
48
+ /**
49
+ * Effect-based absolute path resolution with idiomatic TaggedError failures.
50
+ *
51
+ * - Succeeds with a branded `ExtensionPath` string.
52
+ * - Fails with `PlatformNotSupportedError` or `ExtensionNotFoundError`.
53
+ *
54
+ * @since 0.16.300
55
+ * @example
56
+ * import { getCrSqliteExtensionPath } from "@effect-native/libcrsql/effect"
57
+ * import { Effect } from "effect"
58
+ *
59
+ * const program = getCrSqliteExtensionPath()
60
+ * Effect.runPromise(program)
61
+ */
62
+ export declare const getCrSqliteExtensionPath: (platform?: Platform) => Effect.Effect<ExtensionPath, PlatformNotSupportedError | ExtensionNotFoundError>;
63
+ /**
64
+ * Supported platform-arch identifiers.
65
+ * @since 0.16.300
66
+ */
67
+ export type Platform = _Platform;
68
+ /**
69
+ * List of supported platforms.
70
+ * @since 0.16.300
71
+ */
72
+ export declare const SUPPORTED_PLATFORMS: readonly _Platform[];
73
+ export {};
74
+ //# sourceMappingURL=effect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../src/effect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,EAAQ,MAAM,EAAE,MAAM,QAAQ,CAAA;AAS5C,OAAO,KAAK,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,eAAe,CAAA;;;;AAE1D;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,+BAA8C;IAC3F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAClD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;CAClC,CAAC;IACA;;OAEG;IACH,IAAa,OAAO,WAInB;CACF;;;;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,4BAA2C;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B,CAAC;CAAG;AAEL;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;AACjE;;;GAGG;AACH,eAAO,MAAM,aAAa,kCAAiC,CAAA;AAG3D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,GACnC,WAAW,QAAQ,KAClB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,yBAAyB,GAAG,sBAAsB,CA+B9E,CAAA;AAEJ;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAA;AAEhC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,sBAAuB,CAAA"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Effect entrypoint: idiomatic Effect API with TaggedError failures.
3
+ *
4
+ * @since 0.16.300
5
+ */
6
+ import { Brand, Data, Effect } from "effect";
7
+ import * as fs from "node:fs";
8
+ import { fileURLToPath } from "node:url";
9
+ import { buildRelativeLibraryPath, detectPlatform, isSupportedPlatform, SUPPORTED_PLATFORMS as _SUPPORTED_PLATFORMS } from "./platform.js";
10
+ /**
11
+ * Error indicating that a platform-arch combination is not supported.
12
+ * @since 0.16.300
13
+ */
14
+ export class PlatformNotSupportedError extends /*#__PURE__*/Data.TaggedError("PlatformNotSupportedError") {
15
+ /**
16
+ * @since 0.16.300
17
+ */
18
+ get message() {
19
+ return `Platform "${this.platform}" is not supported. Detected: ${this.detectedPlatform}-${this.detectedArch}. Supported: ${this.supportedPlatforms.join(", ")}`;
20
+ }
21
+ }
22
+ /**
23
+ * Error indicating that the resolved binary path does not exist.
24
+ * @since 0.16.300
25
+ */
26
+ export class ExtensionNotFoundError extends /*#__PURE__*/Data.TaggedError("ExtensionNotFoundError") {}
27
+ /**
28
+ * Brand constructor for `ExtensionPath`.
29
+ * @since 0.16.300
30
+ */
31
+ export const ExtensionPath = /*#__PURE__*/Brand.nominal();
32
+ // Uses a best-effort Node fs sync check without depending on @effect/platform.
33
+ /**
34
+ * Effect-based absolute path resolution with idiomatic TaggedError failures.
35
+ *
36
+ * - Succeeds with a branded `ExtensionPath` string.
37
+ * - Fails with `PlatformNotSupportedError` or `ExtensionNotFoundError`.
38
+ *
39
+ * @since 0.16.300
40
+ * @example
41
+ * import { getCrSqliteExtensionPath } from "@effect-native/libcrsql/effect"
42
+ * import { Effect } from "effect"
43
+ *
44
+ * const program = getCrSqliteExtensionPath()
45
+ * Effect.runPromise(program)
46
+ */
47
+ export const getCrSqliteExtensionPath = platform => Effect.gen(function* () {
48
+ const target = platform ?? detectPlatform();
49
+ if (!isSupportedPlatform(target)) {
50
+ return yield* Effect.fail(new PlatformNotSupportedError({
51
+ platform: target,
52
+ supportedPlatforms: SUPPORTED_PLATFORMS,
53
+ detectedArch: process.arch,
54
+ detectedPlatform: process.platform
55
+ }));
56
+ }
57
+ const abs = fileURLToPath(new URL(`../${buildRelativeLibraryPath(target)}`, import.meta.url));
58
+ const exists = yield* Effect.sync(() => {
59
+ try {
60
+ // Synchronous check is acceptable here since this path is computed
61
+ // infrequently and typically only once per process.
62
+ fs.accessSync(abs);
63
+ return true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ });
68
+ if (!exists) {
69
+ return yield* Effect.fail(new ExtensionNotFoundError({
70
+ path: abs,
71
+ platform: target
72
+ }));
73
+ }
74
+ return ExtensionPath(abs);
75
+ });
76
+ /**
77
+ * List of supported platforms.
78
+ * @since 0.16.300
79
+ */
80
+ export const SUPPORTED_PLATFORMS = _SUPPORTED_PLATFORMS;
81
+ //# sourceMappingURL=effect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect.js","names":["Brand","Data","Effect","fs","fileURLToPath","buildRelativeLibraryPath","detectPlatform","isSupportedPlatform","SUPPORTED_PLATFORMS","_SUPPORTED_PLATFORMS","PlatformNotSupportedError","TaggedError","message","platform","detectedPlatform","detectedArch","supportedPlatforms","join","ExtensionNotFoundError","ExtensionPath","nominal","getCrSqliteExtensionPath","gen","target","fail","process","arch","abs","URL","import","meta","url","exists","sync","accessSync","path"],"sources":["../../src/effect.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;AAKA,SAASA,KAAK,EAAEC,IAAI,EAAEC,MAAM,QAAQ,QAAQ;AAC5C,OAAO,KAAKC,EAAE,MAAM,SAAS;AAC7B,SAASC,aAAa,QAAQ,UAAU;AACxC,SACEC,wBAAwB,EACxBC,cAAc,EACdC,mBAAmB,EACnBC,mBAAmB,IAAIC,oBAAoB,QACtC,eAAe;AAGtB;;;;AAIA,OAAM,MAAOC,yBAA0B,sBAAQT,IAAI,CAACU,WAAW,CAAC,2BAA2B,CAKzF;EACA;;;EAGA,IAAaC,OAAOA,CAAA;IAClB,OAAO,aAAa,IAAI,CAACC,QAAQ,iCAAiC,IAAI,CAACC,gBAAgB,IAAI,IAAI,CAACC,YAAY,gBAC1G,IAAI,CAACC,kBAAkB,CAACC,IAAI,CAAC,IAAI,CACnC,EAAE;EACJ;;AAGF;;;;AAIA,OAAM,MAAOC,sBAAuB,sBAAQjB,IAAI,CAACU,WAAW,CAAC,wBAAwB,CAGnF;AAOF;;;;AAIA,OAAO,MAAMQ,aAAa,gBAAGnB,KAAK,CAACoB,OAAO,EAAiB;AAE3D;AACA;;;;;;;;;;;;;;AAcA,OAAO,MAAMC,wBAAwB,GACnCR,QAAmB,IAEnBX,MAAM,CAACoB,GAAG,CAAC,aAAS;EAClB,MAAMC,MAAM,GAAGV,QAAQ,IAAIP,cAAc,EAAE;EAC3C,IAAI,CAACC,mBAAmB,CAACgB,MAAM,CAAC,EAAE;IAChC,OAAO,OAAOrB,MAAM,CAACsB,IAAI,CACvB,IAAId,yBAAyB,CAAC;MAC5BG,QAAQ,EAAEU,MAAM;MAChBP,kBAAkB,EAAER,mBAAmB;MACvCO,YAAY,EAAEU,OAAO,CAACC,IAAI;MAC1BZ,gBAAgB,EAAEW,OAAO,CAACZ;KAC3B,CAAC,CACH;EACH;EACA,MAAMc,GAAG,GAAGvB,aAAa,CAAC,IAAIwB,GAAG,CAAC,MAAMvB,wBAAwB,CAACkB,MAAM,CAAC,EAAE,EAAEM,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC,CAAC;EAE7F,MAAMC,MAAM,GAAG,OAAO9B,MAAM,CAAC+B,IAAI,CAAC,MAAK;IACrC,IAAI;MACF;MACA;MACA9B,EAAE,CAAC+B,UAAU,CAACP,GAAG,CAAC;MAClB,OAAO,IAAI;IACb,CAAC,CAAC,MAAM;MACN,OAAO,KAAK;IACd;EACF,CAAC,CAAC;EAEF,IAAI,CAACK,MAAM,EAAE;IACX,OAAO,OAAO9B,MAAM,CAACsB,IAAI,CAAC,IAAIN,sBAAsB,CAAC;MAAEiB,IAAI,EAAER,GAAG;MAAEd,QAAQ,EAAEU;IAAM,CAAE,CAAC,CAAC;EACxF;EAEA,OAAOJ,aAAa,CAACQ,GAAG,CAAC;AAC3B,CAAC,CAAC;AAQJ;;;;AAIA,OAAO,MAAMnB,mBAAmB,GAAGC,oBAAoB","ignoreList":[]}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@effect-native/libcrsql",
3
- "version": "0.16.301",
3
+ "version": "4.0.0",
4
4
  "description": "Absolute paths to cr-sqlite extension binaries for Node.js with optional Effect API",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/effect-native/effect-native.git",
9
- "directory": "packages-native/libcrsql"
9
+ "directory": "packages/libcrsql"
10
10
  },
11
11
  "sideEffects": [
12
12
  "./dist/cjs/index.js",
@@ -18,15 +18,11 @@
18
18
  ],
19
19
  "homepage": "https://github.com/effect-native/effect-native",
20
20
  "peerDependencies": {
21
- "effect": "*",
22
- "@effect/platform": "*"
21
+ "effect": "^4.0.0-beta.0"
23
22
  },
24
23
  "peerDependenciesMeta": {
25
24
  "effect": {
26
25
  "optional": true
27
- },
28
- "@effect/platform": {
29
- "optional": true
30
26
  }
31
27
  },
32
28
  "publishConfig": {
package/src/effect.ts CHANGED
@@ -27,7 +27,7 @@ export class PlatformNotSupportedError extends Data.TaggedError("PlatformNotSupp
27
27
  /**
28
28
  * @since 0.16.300
29
29
  */
30
- get message() {
30
+ override get message() {
31
31
  return `Platform "${this.platform}" is not supported. Detected: ${this.detectedPlatform}-${this.detectedArch}. Supported: ${
32
32
  this.supportedPlatforms.join(", ")
33
33
  }`