@toggld/browser 0.0.0-stage → 0.1.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.
@@ -0,0 +1,43 @@
1
+ import { a as ToggldClientOptions, c as FlagMetadata, i as EvaluationDetails, l as FlagValue, n as ClientSnapshot, o as ErrorCode, r as ClientStatus, s as EvaluationContext, t as ToggldClient$1, u as Reason } from "./client-BQFClvyL.js";
2
+ import { Context, Effect, Layer, Scope, Stream } from "effect";
3
+ /** The client's surface as effects. Every effect is non-failing. */
4
+ export interface ToggldClientShape {
5
+ /**
6
+ * The underlying Promise client, for code that is not Effect, for example
7
+ * `<ToggldProvider client={…}>` from `@toggld/react`.
8
+ */
9
+ readonly client: ToggldClient$1;
10
+ /** Completes once the first values arrive, or a failure makes that impossible. */
11
+ readonly ready: Effect.Effect<void>;
12
+ /** Fetch fresh values for the current context now. */
13
+ readonly refresh: Effect.Effect<void>;
14
+ /** Evaluate for a new context (replaced, not merged). Completes when the request settles. */
15
+ readonly setContext: (context: EvaluationContext) => Effect.Effect<void>;
16
+ /** The current state. */
17
+ readonly snapshot: Effect.Effect<ClientSnapshot>;
18
+ /** The current state, then every change to it, until the stream is interrupted. */
19
+ readonly changes: Stream.Stream<ClientSnapshot>;
20
+ readonly evaluate: (key: string, defaultValue: FlagValue) => Effect.Effect<EvaluationDetails<FlagValue>>;
21
+ readonly allFlags: Effect.Effect<ReadonlyArray<EvaluationDetails<FlagValue>>>;
22
+ readonly getBooleanValue: (key: string, defaultValue: boolean) => Effect.Effect<boolean>;
23
+ readonly getBooleanDetails: (key: string, defaultValue: boolean) => Effect.Effect<EvaluationDetails<boolean>>;
24
+ readonly getStringValue: (key: string, defaultValue: string) => Effect.Effect<string>;
25
+ readonly getStringDetails: (key: string, defaultValue: string) => Effect.Effect<EvaluationDetails<string>>;
26
+ readonly getNumberValue: (key: string, defaultValue: number) => Effect.Effect<number>;
27
+ readonly getNumberDetails: (key: string, defaultValue: number) => Effect.Effect<EvaluationDetails<number>>;
28
+ readonly getObjectValue: <T extends FlagValue>(key: string, defaultValue: T) => Effect.Effect<T>;
29
+ readonly getObjectDetails: <T extends FlagValue>(key: string, defaultValue: T) => Effect.Effect<EvaluationDetails<T>>;
30
+ }
31
+ declare const ToggldClient_base: Context.ServiceClass<ToggldClient, "@toggld/browser/ToggldClient", ToggldClientShape>;
32
+ /** The Toggld browser client as an Effect service. */
33
+ export declare class ToggldClient extends ToggldClient_base {}
34
+ /** Wrap an existing Promise client. Closing it stays the caller's job. */
35
+ export declare const fromClient: (client: ToggldClient$1) => ToggldClientShape;
36
+ /** Create a client owned by the current scope: it closes when the scope does. */
37
+ export declare const make: (options: ToggldClientOptions) => Effect.Effect<ToggldClientShape, never, Scope.Scope>;
38
+ /**
39
+ * A layer that provides {@link ToggldClient}. It starts loading at once but
40
+ * does not wait for values; `yield* flags.ready` to wait.
41
+ */
42
+ export declare const layer: (options: ToggldClientOptions) => Layer.Layer<ToggldClient>;
43
+ export type { ClientSnapshot, ClientStatus, ErrorCode, EvaluationContext, EvaluationDetails, FlagMetadata, FlagValue, Reason, ToggldClientOptions };
package/dist/effect.js ADDED
@@ -0,0 +1,62 @@
1
+ import { t as ToggldClient$1 } from "./client-BwTN-sJD.js";
2
+ import { Context, Effect, Layer, Queue, Stream } from "effect";
3
+ // src/effect.ts
4
+ /**
5
+ * `@toggld/browser/effect` — the native Effect API. Needs the optional `effect`
6
+ * peer dependency (`^4.0.5`); the default `@toggld/browser` entry does not.
7
+ *
8
+ * The client as a scoped service: build a {@link layer} from your options and
9
+ * `yield* ToggldClient`. The layer's scope owns the client and closes it.
10
+ *
11
+ * ```ts
12
+ * import { Effect, Stream } from "effect"
13
+ * import { ToggldClient, layer } from "@toggld/browser/effect"
14
+ *
15
+ * const program = Effect.gen(function* () {
16
+ * const flags = yield* ToggldClient
17
+ * yield* flags.ready
18
+ * const on = yield* flags.getBooleanValue("new-checkout", false)
19
+ * // Every state change, starting with the current state:
20
+ * yield* flags.changes.pipe(Stream.runForEach((s) => Effect.log(s.status)))
21
+ * })
22
+ *
23
+ * program.pipe(Effect.provide(layer({ publicToken, context })), Effect.runFork)
24
+ * ```
25
+ *
26
+ * This is a thin wrapper over the dependency-free client in
27
+ * `./internal/client.ts`, which is the implementation of both entries.
28
+ */
29
+ /** The Toggld browser client as an Effect service. */
30
+ var ToggldClient = class extends Context.Service()("@toggld/browser/ToggldClient") {};
31
+ /** Wrap an existing Promise client. Closing it stays the caller's job. */
32
+ const fromClient = (client) => ({
33
+ client,
34
+ ready: Effect.promise(() => client.ready()),
35
+ refresh: Effect.promise(() => client.refresh()),
36
+ setContext: (context) => Effect.promise(() => client.setContext(context)),
37
+ snapshot: Effect.sync(() => client.getSnapshot()),
38
+ changes: Stream.callback((queue) => Effect.acquireRelease(Effect.sync(() => {
39
+ Queue.offerUnsafe(queue, client.getSnapshot());
40
+ return client.subscribe(() => {
41
+ Queue.offerUnsafe(queue, client.getSnapshot());
42
+ });
43
+ }), (unsubscribe) => Effect.sync(unsubscribe))),
44
+ evaluate: (key, defaultValue) => Effect.sync(() => client.evaluate(key, defaultValue)),
45
+ allFlags: Effect.sync(() => client.allFlags()),
46
+ getBooleanValue: (key, defaultValue) => Effect.sync(() => client.getBooleanValue(key, defaultValue)),
47
+ getBooleanDetails: (key, defaultValue) => Effect.sync(() => client.getBooleanDetails(key, defaultValue)),
48
+ getStringValue: (key, defaultValue) => Effect.sync(() => client.getStringValue(key, defaultValue)),
49
+ getStringDetails: (key, defaultValue) => Effect.sync(() => client.getStringDetails(key, defaultValue)),
50
+ getNumberValue: (key, defaultValue) => Effect.sync(() => client.getNumberValue(key, defaultValue)),
51
+ getNumberDetails: (key, defaultValue) => Effect.sync(() => client.getNumberDetails(key, defaultValue)),
52
+ getObjectValue: (key, defaultValue) => Effect.sync(() => client.getObjectValue(key, defaultValue)),
53
+ getObjectDetails: (key, defaultValue) => Effect.sync(() => client.getObjectDetails(key, defaultValue))
54
+ });
55
+ /** Create a client owned by the current scope: it closes when the scope does. */
56
+ const make = (options) => Effect.acquireRelease(Effect.sync(() => new ToggldClient$1(options)), (client) => Effect.sync(() => client.close())).pipe(Effect.map(fromClient));
57
+ /**
58
+ * A layer that provides {@link ToggldClient}. It starts loading at once but
59
+ * does not wait for values; `yield* flags.ready` to wait.
60
+ */
61
+ const layer = (options) => Layer.effect(ToggldClient, make(options));
62
+ export { ToggldClient, fromClient, layer, make };
@@ -0,0 +1,2 @@
1
+ import { a as ToggldClientOptions, c as FlagMetadata, i as EvaluationDetails, l as FlagValue, n as ClientSnapshot, o as ErrorCode, r as ClientStatus, s as EvaluationContext, t as ToggldClient, u as Reason } from "./client-BQFClvyL.js";
2
+ export { type ClientSnapshot, type ClientStatus, type ErrorCode, type EvaluationContext, type EvaluationDetails, type FlagMetadata, type FlagValue, type Reason, ToggldClient, type ToggldClientOptions };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { t as ToggldClient } from "./client-BwTN-sJD.js";
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@toggld/browser",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Toggld SDK for browsers — evaluates every flag for the current user in one request and serves values synchronously from memory. Zero dependencies; optional native Effect API via @toggld/browser/effect.",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://toggld.io",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/toggld/toggld.git",
10
+ "directory": "packages/browser"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/toggld/toggld/issues"
14
+ },
15
+ "keywords": [
16
+ "feature-flags",
17
+ "openfeature",
18
+ "ofrep",
19
+ "toggld",
20
+ "browser",
21
+ "effect"
22
+ ],
23
+ "type": "module",
24
+ "sideEffects": false,
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "exports": {
29
+ "./package.json": "./package.json",
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./effect": {
35
+ "types": "./dist/effect.d.ts",
36
+ "default": "./dist/effect.js"
37
+ }
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "peerDependencies": {
43
+ "effect": "^4.0.5"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "effect": {
47
+ "optional": true
48
+ }
49
+ },
50
+ "devDependencies": {
51
+ "effect": "4.0.6",
52
+ "tsdown": "^0.23.2",
53
+ "typescript": "6.0.3",
54
+ "@toggld/server": "0.1.0",
55
+ "@toggld/spec": "0.1.0"
56
+ },
57
+ "scripts": {
58
+ "build": "tsdown",
59
+ "size": "tsdown && node scripts/check-size.mjs",
60
+ "typecheck": "tsc --noEmit",
61
+ "test": "vitest run",
62
+ "test:watch": "vitest"
63
+ }
6
64
  }