khotan-data 0.1.0 → 0.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.
@@ -0,0 +1,11 @@
1
+ import { cache } from "./cache";
2
+
3
+ export const cin7ProductsSnapshotCache = cache({
4
+ name: "cin7-products-snapshot",
5
+ scope: {
6
+ plug: "cin7",
7
+ resource: "products",
8
+ flow: "cin7-to-pollinate-products-relay",
9
+ },
10
+ ttl: "6h",
11
+ });
@@ -0,0 +1,58 @@
1
+ // ============================================================================
2
+ // Cache — durable sync-state storage for flows, relays, and webhooks
3
+ // Generated by khotan CLI · https://github.com/khotan-data
4
+ //
5
+ // This file defines the cache() builder and types. Create named cache
6
+ // definitions for expensive upstream snapshots, checkpoints, and dedupe markers,
7
+ // then register them in your khotan.ts factory config.
8
+ // ============================================================================
9
+
10
+ import type { CacheRegistration, CacheScope } from "khotan-data/factory";
11
+
12
+ export interface CacheConfig {
13
+ /** Unique cache name used by runtime helpers and DB registration */
14
+ name: string;
15
+ /** Optional ownership metadata for humans and runtime validation */
16
+ scope?: CacheScope;
17
+ /** Optional default TTL like "30m", "6h", or 86400 */
18
+ ttl?: string | number;
19
+ }
20
+
21
+ export function cache(config: CacheConfig): CacheRegistration {
22
+ return {
23
+ name: config.name,
24
+ scope: config.scope,
25
+ ttl: config.ttl,
26
+ };
27
+ }
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Usage Example (create a file like caches/cin7-products-snapshot.ts)
31
+ // ---------------------------------------------------------------------------
32
+ //
33
+ // import { cache } from "./cache";
34
+ //
35
+ // export const cin7ProductsSnapshotCache = cache({
36
+ // name: "cin7-products-snapshot",
37
+ // scope: {
38
+ // plug: "cin7",
39
+ // resource: "products",
40
+ // flow: "cin7-to-pollinate-products-relay",
41
+ // },
42
+ // ttl: "6h",
43
+ // });
44
+ //
45
+ // Then register in your khotan config:
46
+ //
47
+ // import { cin7ProductsSnapshotCache } from "./caches/cin7-products-snapshot";
48
+ //
49
+ // const khotanData = khotan({
50
+ // adapter: drizzleAdapter(db),
51
+ // caches: [cin7ProductsSnapshotCache],
52
+ // plugs: [...],
53
+ // });
54
+ //
55
+ // Flow, relay, catch, and pass workflows can then use:
56
+ // await khotanCache(ctx, "cin7-products-snapshot").get("all-products");
57
+ // await khotanCache(ctx, "cin7-products-snapshot").set("all-products", payload);
58
+ // await khotanCache(ctx, "cin7-products-snapshot").delete("all-products");
@@ -24,6 +24,8 @@ export interface CatchContext {
24
24
  headers: Record<string, string>;
25
25
  /** Khotan run ID created for this webhook handler execution */
26
26
  khotanRunId: string;
27
+ /** Internal Khotan instance identifier for helper APIs */
28
+ khotanInstanceId: string;
27
29
  }
28
30
 
29
31
  // ---------------------------------------------------------------------------
@@ -73,19 +75,29 @@ export function catchEvent(config: CatchConfig): CatchRegistration {
73
75
  // Usage Example (create a file like webhooks/pollinate-catch.ts)
74
76
  // ---------------------------------------------------------------------------
75
77
  //
78
+ // import { khotanCache } from "khotan-data/factory";
76
79
  // import { catchEvent, type CatchContext } from "./catch";
77
80
  // Khotan already records webhook deliveries in khotan_webhook_events and links
78
- // them to khotan_runs. Use your catch workflow for app-specific side effects.
81
+ // them to khotan_runs. Use your catch workflow for app-specific side effects
82
+ // and optionally khotanCache(ctx, "name") for dedupe or cursor state.
79
83
  //
80
84
  // async function pollinateCatchWorkflow(ctx: CatchContext) {
81
85
  // "use workflow";
82
86
  //
83
87
  // async function notifyOps() {
84
88
  // "use step";
89
+ // const cache = khotanCache(ctx, "pollinate-webhook-markers");
90
+ // const eventId = String(ctx.event["id"] ?? "");
91
+ // if (eventId && (await cache.get<boolean>(eventId))) return;
92
+ //
85
93
  // console.log("Handled webhook", {
86
94
  // eventType: ctx.eventType,
87
95
  // khotanRunId: ctx.khotanRunId,
88
96
  // });
97
+ //
98
+ // if (eventId) {
99
+ // await cache.set(eventId, true);
100
+ // }
89
101
  // }
90
102
  //
91
103
  // await notifyOps();
@@ -5,7 +5,8 @@
5
5
  // This file defines the inflow() builder and types. Create per-service flow
6
6
  // files (e.g. shopify-products.ts) using this builder to pull records from an
7
7
  // external service, transform them, and load them into your app with durable,
8
- // retryable Vercel Workflow steps.
8
+ // retryable Vercel Workflow steps. Inflow workflows can also use
9
+ // khotanCache(ctx, "name") for checkpoints and last-seen markers across runs.
9
10
  // ============================================================================
10
11
 
11
12
  import type {
@@ -47,11 +48,10 @@ export function inflow(config: InflowConfig): FlowRegistration {
47
48
  // Usage Example (create a file like flows/shopify-products.ts)
48
49
  // ---------------------------------------------------------------------------
49
50
  //
50
- // import { inflow, type InflowContext } from "./inflow";
51
+ // import { bindWorkflowPlug, inflow, type InflowContext, sendUpdate } from "khotan-data/factory";
51
52
  // import { db } from "@/db";
52
53
  // import { products } from "@/db/schema";
53
54
  // import { shopifyPlug } from "../plugs/shopify";
54
- // import { sendUpdate } from "khotan-data/factory";
55
55
  //
56
56
  // async function shopifyProductsWorkflow(ctx: InflowContext) {
57
57
  // "use workflow";
@@ -64,10 +64,9 @@ export function inflow(config: InflowConfig): FlowRegistration {
64
64
  // runType: ctx.runType,
65
65
  // });
66
66
  // await sendUpdate({ message: "Starting Shopify products inflow" });
67
+ // const shopify = bindWorkflowPlug(shopifyPlug, ctx);
67
68
  //
68
- // const response = await shopifyPlug.get<{ data?: Array<{ id: string; sku?: string }> }>("/products", {
69
- // vars: ctx.vars,
70
- // });
69
+ // const response = await shopify.get<{ data?: Array<{ id: string; sku?: string }> }>("/products");
71
70
  // const records = Array.isArray(response.data) ? response.data : [];
72
71
  // await sendUpdate({ message: `Fetched ${records.length} products`, extracted: records.length });
73
72
  //
@@ -1,5 +1,5 @@
1
1
  // ============================================================================
2
- // Khotan Config — register your plugs and flows here
2
+ // Khotan Config — register your plugs, caches, and flows here
3
3
  // Generated by khotan CLI · https://github.com/khotan-data
4
4
  //
5
5
  // Import your Drizzle database instance and register plugs below.
@@ -14,12 +14,12 @@ const khotanData = khotan({
14
14
  adapter: drizzleAdapter(db),
15
15
 
16
16
  // Resources define logical entity types for cross-referencing across plugs.
17
- // The connectField names the field used to match records (e.g. "sku").
17
+ // The mapping block declares the shared identity contract for that resource.
18
18
  resources: [
19
19
  // Example resource registration:
20
20
  //
21
- // { name: "products", connectField: "sku", description: "Product catalog" },
22
- // { name: "orders", connectField: "order_number" },
21
+ // { name: "products", mapping: { connectField: "sku" }, description: "Product catalog" },
22
+ // { name: "orders", mapping: { connectField: "order_number" } },
23
23
  ],
24
24
 
25
25
  plugs: [
@@ -35,6 +35,15 @@ const khotanData = khotan({
35
35
  // ],
36
36
  // },
37
37
  ],
38
+
39
+ // Caches store durable key/value state for relays, inflows, outflows, and
40
+ // webhook workflows. Register named caches you want to access via
41
+ // khotanCache(ctx, "cache-name") or khotanData.cache("cache-name").
42
+ caches: [
43
+ // Example cache registration:
44
+ //
45
+ // cin7ProductsSnapshotCache,
46
+ ],
38
47
  });
39
48
 
40
49
  export default khotanData;