@creact-labs/creact 0.2.1 → 0.2.3

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
@@ -1,100 +1,60 @@
1
- # CReact
2
-
3
- **Declarative reactive runtime for AI agents, cloud infrastructure, and automation.**
4
-
5
- Build complex workflows with JSX. Describe *what* you want — CReact figures out *how*.
6
-
7
- ## Install
8
-
9
- ```bash
10
- npm install @creact-labs/creact
11
- ```
1
+ <p align="center">
2
+ <img src="https://img.shields.io/npm/v/@creact-labs/creact" alt="npm version" />
3
+ <img src="https://img.shields.io/npm/l/@creact-labs/creact" alt="license" />
4
+ </p>
12
5
 
13
- ## Example: AI Content Pipeline
6
+ # CReact
14
7
 
15
- A workflow that generates blog posts and publishes to multiple channels — all reactive and declarative:
8
+ What if you could generate SEO-optimized product pages by researching competitors automatically?
16
9
 
17
10
  ```tsx
18
- import { CReact, renderCloudDOM, useInstance, createSignal } from '@creact-labs/creact';
19
-
20
- // 🤖 AI generates content from a topic
21
- function AIWriter({ topic, children }) {
22
- const content = useInstance(OpenAICompletion, {
23
- model: 'gpt-4',
24
- prompt: `Write a blog post about: ${topic}`,
25
- });
26
- return children(content);
27
- }
28
-
29
- // 📝 Publish to your blog
30
- function BlogPost({ title, content }) {
31
- return useInstance(WordPressPost, { title, content, status: 'published' });
32
- }
33
-
34
- // 🐦 Share on social
35
- function Tweet({ content }) {
36
- return useInstance(TwitterPost, {
37
- text: content.summary(),
38
- thread: true,
39
- });
40
- }
41
-
42
- // 💬 Notify your team
43
- function SlackNotify({ channel, message }) {
44
- return useInstance(SlackMessage, { channel, text: message });
45
- }
46
-
47
- // 🔗 Compose the pipeline
48
- function ContentPipeline({ topic }) {
49
- return (
50
- <AIWriter topic={topic}>
51
- {(content) => (
52
- <>
53
- <BlogPost title={content.title()} content={content.body()} />
54
- <Tweet content={content} />
55
- <SlackNotify
56
- channel="#content"
57
- message={`✨ New post published: ${content.title()}`}
58
- />
59
- </>
11
+ <FormTrigger fields={['productTitle']}>
12
+ {(form) => (
13
+ <GoogleSearch query={`intitle:"${form.productTitle()}" pricing OR features`}>
14
+ {(results) => (
15
+ <ExtractText items={results.items()} fields={['title', 'snippet']}>
16
+ {(extracted) => (
17
+ <GeminiCompletion prompt={`Generate SEO meta and product description:\n${extracted.text()}`}>
18
+ {(content) => (
19
+ <>
20
+ <ParseSections text={content.output()} format="seo,product">
21
+ {(parsed) => (
22
+ <GoogleSheetAppend doc="catalog" row={parsed.fields()} />
23
+ )}
24
+ </ParseSections>
25
+
26
+ <SlackMessage channel="#products" text={`New: ${form.productTitle()}`} />
27
+ </>
28
+ )}
29
+ </GeminiCompletion>
30
+ )}
31
+ </ExtractText>
60
32
  )}
61
- </AIWriter>
62
- );
63
- }
64
-
65
- // Run it
66
- await renderCloudDOM(<ContentPipeline topic="Why CReact changes everything" />);
33
+ </GoogleSearch>
34
+ )}
35
+ </FormTrigger>
67
36
  ```
68
37
 
69
- **Change the topiceverything updates.** The blog post regenerates, tweet updates, Slack notifies.
38
+ Form SearchExtract AI branches to Sheets and Slack. Each construct is one action.
70
39
 
71
- ## Why CReact?
72
-
73
- | Traditional Approach | CReact |
74
- |---------------------|--------|
75
- | Imperative scripts that break | Declarative specs that reconcile |
76
- | Manual dependency tracking | Automatic reactive updates |
77
- | Scattered state across files | Single source of truth |
78
- | Hard to test and reason about | Composable, testable components |
40
+ ```bash
41
+ npm install @creact-labs/creact
42
+ ```
79
43
 
80
- ## The Four Pillars
44
+ ## How it works
81
45
 
82
- **Declarative** Describe what you want, not how to get it.
46
+ **Constructs** define what you want (props) and what you get (outputs).
83
47
 
84
- **Universal** Works for AI agents, cloud infrastructure, APIs, anything.
48
+ **Components** compose constructs with JSX. Dependencies flow through render props.
85
49
 
86
- **Reactive** Automatically responds when things change.
50
+ **Providers** execute constructs against real infrastructure (AWS, Terraform, APIs).
87
51
 
88
- **Runtime** Keeps running continuously, handles events, recovers from crashes.
52
+ **Backends** persist state for crash recovery and incremental updates.
89
53
 
90
54
  ## Documentation
91
55
 
92
- - [Tutorial: Build an AI Agent](./docs/getting-started/1-setup.md)
93
- - [Thinking in CReact](./docs/concepts/thinking-in-creact.md)
94
- - [Constructs](./docs/concepts/constructs.md)
95
- - [Components](./docs/concepts/components.md)
96
- - [Reactivity](./docs/concepts/reactivity.md)
97
- - [Providers](./docs/concepts/providers.md)
56
+ - [Tutorial](./docs/getting-started/1-setup.md) — Build an AI agent with Wikipedia search
57
+ - [Concepts](./docs/concepts/index.md) — Core mental model
98
58
 
99
59
  ## License
100
60
 
package/dist/cli.js CHANGED
@@ -8,8 +8,10 @@
8
8
  * Runs a CReact application with the configured provider.
9
9
  * Uses tsx under the hood to execute TypeScript/TSX files.
10
10
  */
11
- import { spawn } from 'node:child_process';
12
- import { resolve } from 'node:path';
11
+ import { tsImport } from 'tsx/esm/api';
12
+ import { watch } from 'node:fs/promises';
13
+ import { dirname, resolve } from 'node:path';
14
+ import { pathToFileURL } from 'node:url';
13
15
  function showHelp() {
14
16
  console.log(`
15
17
  CReact CLI
@@ -41,6 +43,16 @@ Example entrypoint:
41
43
  }
42
44
  `);
43
45
  }
46
+ async function runEntrypoint(entrypoint) {
47
+ const url = pathToFileURL(entrypoint).href;
48
+ // FIXME: Cache-busting causes memory leak as old modules stay in V8 cache.
49
+ // Acceptable for dev watch mode, but consider worker threads for long sessions.
50
+ const cacheBustUrl = `${url}?t=${Date.now()}`;
51
+ const module = await tsImport(cacheBustUrl, import.meta.url);
52
+ if (typeof module.default === 'function') {
53
+ await module.default();
54
+ }
55
+ }
44
56
  async function main() {
45
57
  const args = process.argv.slice(2);
46
58
  if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
@@ -48,11 +60,11 @@ async function main() {
48
60
  process.exit(0);
49
61
  }
50
62
  // Parse --watch / -w flag and get entrypoint
51
- let watch = false;
63
+ let watchMode = false;
52
64
  let entrypointArg;
53
65
  const firstArg = args[0];
54
66
  if (firstArg === '--watch' || firstArg === '-w') {
55
- watch = true;
67
+ watchMode = true;
56
68
  const arg = args[1];
57
69
  if (!arg) {
58
70
  console.error('Error: --watch requires an entrypoint');
@@ -68,21 +80,18 @@ async function main() {
68
80
  process.exit(0);
69
81
  }
70
82
  const entrypoint = resolve(process.cwd(), entrypointArg);
71
- // Build tsx command
72
- const tsxArgs = watch ? ['tsx', 'watch', entrypoint] : ['tsx', entrypoint];
73
- // Spawn tsx to run the entrypoint
74
- const child = spawn('npx', tsxArgs, {
75
- stdio: 'inherit',
76
- cwd: process.cwd(),
77
- shell: true,
78
- });
79
- child.on('error', (error) => {
80
- console.error('Error running CReact application:');
81
- console.error(error.message);
82
- process.exit(1);
83
- });
84
- child.on('exit', (code) => {
85
- process.exit(code ?? 0);
86
- });
83
+ // Initial run
84
+ await runEntrypoint(entrypoint);
85
+ // Watch mode: async iterator keeps process alive
86
+ if (watchMode) {
87
+ console.log('Watching for changes...');
88
+ const watcher = watch(dirname(entrypoint), { recursive: true });
89
+ for await (const event of watcher) {
90
+ if (event.filename?.match(/\.(tsx?|jsx?)$/)) {
91
+ console.log(`\nRestarting...`);
92
+ await runEntrypoint(entrypoint);
93
+ }
94
+ }
95
+ }
87
96
  }
88
97
  main();
package/dist/index.d.ts CHANGED
@@ -5,17 +5,9 @@ export { createElement, Fragment, jsx, jsxs } from './jsx/jsx-runtime';
5
5
  export { createContext, useContext } from './primitives/context';
6
6
  export { useInstance } from './primitives/instance';
7
7
  export { createStore } from './primitives/store';
8
- export type { AuditLogEntry, Backend, ChangeSet, DeploymentState, DeploymentStatus, ResourceState, SerializedNode, } from './provider/backend';
9
- export { serializeNode, serializeNodes } from './provider/backend';
8
+ export { createEffect } from './reactive/effect';
9
+ export { CReact, renderCloudDOM } from './runtime/run';
10
+ export type { AuditLogEntry, Backend, DeploymentState } from './provider/backend';
10
11
  export type { OutputChangeEvent, Provider } from './provider/interface';
11
12
  export { createMockProvider } from './provider/interface';
12
- export { createEffect, onCleanup } from './reactive/effect';
13
- export { createSignal } from './reactive/signal';
14
- export { batch, untrack } from './reactive/tracking';
15
- export type { DependencyGraph } from './runtime/reconcile';
16
- export { buildDependencyGraph, computeParallelBatches, hasNewNodes, reconcile, topologicalSort, } from './runtime/reconcile';
17
- export type { CReactOptions } from './runtime/run';
18
- export { CReact, renderCloudDOM, resetRuntime, run, runWithBackend } from './runtime/run';
19
- export type { StateMachineOptions } from './runtime/state-machine';
20
- export { StateMachine } from './runtime/state-machine';
21
- export type { Accessor, Context, Fiber, InstanceNode, JSXElement, OutputAccessors, SetStoreFunction, Setter, } from './types';
13
+ export type { Context, InstanceNode, JSXElement, OutputAccessors, SetStoreFunction, } from './types';
package/dist/index.js CHANGED
@@ -7,16 +7,7 @@ export { createContext, useContext } from './primitives/context';
7
7
  // Primitives
8
8
  export { useInstance } from './primitives/instance';
9
9
  export { createStore } from './primitives/store';
10
- // Backend
11
- export { serializeNode, serializeNodes } from './provider/backend';
12
- // Provider
13
- export { createMockProvider } from './provider/interface';
14
- // Reactive
15
- export { createEffect, onCleanup } from './reactive/effect';
16
- export { createSignal } from './reactive/signal';
17
- export { batch, untrack } from './reactive/tracking';
18
- // Reconciler
19
- export { buildDependencyGraph, computeParallelBatches, hasNewNodes, reconcile, topologicalSort, } from './runtime/reconcile';
10
+ export { createEffect } from './reactive/effect';
20
11
  // Runtime
21
- export { CReact, renderCloudDOM, resetRuntime, run, runWithBackend } from './runtime/run';
22
- export { StateMachine } from './runtime/state-machine';
12
+ export { CReact, renderCloudDOM } from './runtime/run';
13
+ export { createMockProvider } from './provider/interface';
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@creact-labs/creact",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
+ "type": "module",
4
5
  "description": "Declarative universal reactive runtime",
5
6
  "main": "dist/index.js",
6
7
  "types": "dist/index.d.ts",