@schematichq/schematic-typescript-node 1.4.0 → 1.4.2

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
@@ -601,6 +601,97 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
601
601
  }
602
602
  ```
603
603
 
604
+ ## DataStream
605
+
606
+ DataStream enables local flag evaluation by maintaining a WebSocket connection to Schematic and caching flag rules, company, and user data locally.
607
+
608
+ > **Runtime compatibility:** DataStream requires Node.js APIs (`WebSocket`, `EventEmitter`) and is not supported in edge runtimes such as Cloudflare Workers, Vercel Edge Functions, or Deno Deploy. For these runtimes, use [Replicator Mode](#replicator-mode) instead.
609
+
610
+ ### Setup
611
+
612
+ ```ts
613
+ import { SchematicClient } from "@schematichq/schematic-typescript-node";
614
+
615
+ const client = new SchematicClient({
616
+ apiKey: process.env.SCHEMATIC_API_KEY,
617
+ useDataStream: true,
618
+ });
619
+
620
+ // Flag checks are now evaluated locally
621
+ const flagValue = await client.checkFlag(
622
+ { company: { id: "your-company-id" } },
623
+ "some-flag-key",
624
+ );
625
+
626
+ client.close();
627
+ ```
628
+
629
+ ### Configuration options
630
+
631
+ | Option | Type | Default | Description |
632
+ |---|---|---|---|
633
+ | `cacheTTL` | `number` | 24 hours | Cache TTL in milliseconds |
634
+ | `redisClient` | `RedisClient` | — | Redis client for shared caching (uses in-memory cache if not provided) |
635
+ | `redisKeyPrefix` | `string` | `schematic:` | Key prefix for Redis cache entries |
636
+
637
+ ```ts
638
+ import { createClient } from "redis";
639
+ import { SchematicClient } from "@schematichq/schematic-typescript-node";
640
+
641
+ const redisClient = createClient({ url: "redis://localhost:6379" });
642
+ await redisClient.connect();
643
+
644
+ const client = new SchematicClient({
645
+ apiKey: process.env.SCHEMATIC_API_KEY,
646
+ useDataStream: true,
647
+ dataStream: {
648
+ redisClient,
649
+ redisKeyPrefix: "schematic:",
650
+ cacheTTL: 60 * 60 * 1000, // 1 hour
651
+ },
652
+ });
653
+ ```
654
+
655
+ ## Replicator Mode
656
+
657
+ Replicator mode is designed for environments where a separate process (the replicator) manages the WebSocket connection and populates a shared cache. The SDK reads from that cache and evaluates flags locally without establishing its own WebSocket connection.
658
+
659
+ ### Requirements
660
+
661
+ Replicator mode requires a shared cache (Redis or custom cache providers) so the SDK can read data written by the external replicator process.
662
+
663
+ ### Setup
664
+
665
+ ```ts
666
+ import { createClient } from "redis";
667
+ import { SchematicClient } from "@schematichq/schematic-typescript-node";
668
+
669
+ const redisClient = createClient({ url: "redis://localhost:6379" });
670
+ await redisClient.connect();
671
+
672
+ const client = new SchematicClient({
673
+ apiKey: process.env.SCHEMATIC_API_KEY,
674
+ useDataStream: true,
675
+ dataStream: {
676
+ replicatorMode: true,
677
+ redisClient,
678
+ replicatorHealthURL: "http://localhost:8080/health",
679
+ replicatorHealthCheck: 30000, // 30 seconds
680
+ },
681
+ });
682
+ ```
683
+
684
+ ### Configuration options
685
+
686
+ | Option | Type | Default | Description |
687
+ |---|---|---|---|
688
+ | `replicatorMode` | `boolean` | `false` | Enable replicator mode |
689
+ | `redisClient` | `RedisClient` | — | **Required.** Redis client for reading from the shared cache |
690
+ | `redisKeyPrefix` | `string` | `schematic:` | Key prefix for Redis cache entries |
691
+ | `replicatorHealthURL` | `string` | — | URL to poll for replicator health status |
692
+ | `replicatorHealthCheck` | `number` | 30000 | Health check polling interval in milliseconds |
693
+ | `cacheTTL` | `number` | 24 hours | Cache TTL in milliseconds |
694
+
604
695
  ## Testing
605
696
 
606
697
  ### Offline mode
@@ -369,7 +369,6 @@ export declare class BillingClient {
369
369
  * @example
370
370
  * await client.billing.upsertBillingProduct({
371
371
  * externalId: "external_id",
372
- * name: "name",
373
372
  * price: 1.1
374
373
  * })
375
374
  */
@@ -3,14 +3,13 @@ import type * as Schematic from "../../../../index";
3
3
  * @example
4
4
  * {
5
5
  * externalId: "external_id",
6
- * name: "name",
7
6
  * price: 1.1
8
7
  * }
9
8
  */
10
9
  export interface CreateBillingProductRequestBody {
11
10
  externalId: string;
12
11
  isActive?: boolean;
13
- name: string;
12
+ name?: string;
14
13
  price: number;
15
14
  providerType?: Schematic.BillingProviderType;
16
15
  }
@@ -11,6 +11,7 @@ export declare class PlangroupsClient {
11
11
  protected readonly _options: NormalizedClientOptionsWithAuth<PlangroupsClient.Options>;
12
12
  constructor(options: PlangroupsClient.Options);
13
13
  /**
14
+ * @param {Schematic.GetPlanGroupRequest} request
14
15
  * @param {PlangroupsClient.RequestOptions} requestOptions - Request-specific configuration.
15
16
  *
16
17
  * @throws {@link Schematic.UnauthorizedError}
@@ -19,9 +20,11 @@ export declare class PlangroupsClient {
19
20
  * @throws {@link Schematic.InternalServerError}
20
21
  *
21
22
  * @example
22
- * await client.plangroups.getPlanGroup()
23
+ * await client.plangroups.getPlanGroup({
24
+ * includeCompanyCounts: true
25
+ * })
23
26
  */
24
- getPlanGroup(requestOptions?: PlangroupsClient.RequestOptions): core.HttpResponsePromise<Schematic.GetPlanGroupResponse>;
27
+ getPlanGroup(request?: Schematic.GetPlanGroupRequest, requestOptions?: PlangroupsClient.RequestOptions): core.HttpResponsePromise<Schematic.GetPlanGroupResponse>;
25
28
  private __getPlanGroup;
26
29
  /**
27
30
  * @param {Schematic.CreatePlanGroupRequestBody} request
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @example
3
+ * {
4
+ * includeCompanyCounts: true
5
+ * }
6
+ */
7
+ export interface GetPlanGroupRequest {
8
+ includeCompanyCounts?: boolean;
9
+ }
@@ -1,2 +1,3 @@
1
1
  export type { CreatePlanGroupRequestBody } from "./CreatePlanGroupRequestBody";
2
+ export type { GetPlanGroupRequest } from "./GetPlanGroupRequest";
2
3
  export type { UpdatePlanGroupRequestBody } from "./UpdatePlanGroupRequestBody";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Input parameters
3
+ */
4
+ export interface GetPlanGroupParams {
5
+ includeCompanyCounts?: boolean;
6
+ }
@@ -2,5 +2,5 @@ import type * as Schematic from "../../../index";
2
2
  export interface GetPlanGroupResponse {
3
3
  data: Schematic.PlanGroupDetailResponseData;
4
4
  /** Input parameters */
5
- params: Record<string, unknown>;
5
+ params: Schematic.GetPlanGroupParams;
6
6
  }
@@ -1,3 +1,4 @@
1
1
  export * from "./CreatePlanGroupResponse";
2
+ export * from "./GetPlanGroupParams";
2
3
  export * from "./GetPlanGroupResponse";
3
4
  export * from "./UpdatePlanGroupResponse";
@@ -1,6 +1,6 @@
1
- import { EventEmitter } from 'events';
2
1
  import * as Schematic from '../api/types';
3
2
  import { Logger } from '../logger';
3
+ import { LazyEmitter } from './emitter';
4
4
  import type { CacheProvider } from '../cache/types';
5
5
  import { type RedisClient } from '../cache/redis';
6
6
  /**
@@ -36,7 +36,7 @@ export interface DataStreamClientOptions {
36
36
  * DataStreamClient provides a comprehensive client for Schematic's datastream
37
37
  * with caching, flag evaluation, and entity management matching the Go implementation
38
38
  */
39
- export declare class DataStreamClient extends EventEmitter {
39
+ export declare class DataStreamClient extends LazyEmitter {
40
40
  private readonly apiKey;
41
41
  private readonly baseURL?;
42
42
  private readonly logger;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Minimal interface for the subset of EventEmitter we use.
3
+ * Avoids importing the Node.js `events` module at the top level
4
+ * so that edge runtimes (Cloudflare Workers, etc.) can load the
5
+ * module graph without error.
6
+ */
7
+ export interface Emitter {
8
+ on(event: string, listener: (...args: any[]) => void): void;
9
+ emit(event: string, ...args: any[]): boolean;
10
+ removeAllListeners(event?: string): void;
11
+ }
12
+ /**
13
+ * Mixin base class that provides lazy-loaded EventEmitter composition.
14
+ * The Node.js `events` module is only required the first time a listener
15
+ * is registered or an event is emitted, keeping the import out of the
16
+ * module-level dependency graph.
17
+ */
18
+ export declare class LazyEmitter {
19
+ private _emitter;
20
+ private ensureEmitter;
21
+ on(event: string, listener: (...args: any[]) => void): this;
22
+ emit(event: string, ...args: any[]): boolean;
23
+ removeAllListeners(event?: string): this;
24
+ }
@@ -1,6 +1,6 @@
1
- import { EventEmitter } from 'events';
2
1
  import { DataStreamResp, DataStreamBaseReq } from './types';
3
2
  import { Logger } from '../logger';
3
+ import { LazyEmitter } from './emitter';
4
4
  /**
5
5
  * MessageHandlerFunc is a function type for handling incoming datastream messages
6
6
  * Expects parsed DataStreamResp messages
@@ -34,7 +34,7 @@ export interface ClientOptions {
34
34
  /**
35
35
  * DatastreamWSClient represents a Schematic datastream websocket client with automatic reconnection
36
36
  */
37
- export declare class DatastreamWSClient extends EventEmitter {
37
+ export declare class DatastreamWSClient extends LazyEmitter {
38
38
  private readonly url;
39
39
  private readonly headers;
40
40
  private readonly logger;