@neomorph/sdk 0.0.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.
package/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # @neomorph/sdk
2
+
3
+ Advanced theme transformation SDK for web applications. Enables dynamic theme customization through CSS custom properties with cross-origin communication support.
4
+
5
+ [![npm version](https://badge.fury.io/js/@neomorph%2Fsdk.svg)](https://www.npmjs.com/package/@neomorph/sdk)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
7
+
8
+ ## 🎯 Overview
9
+
10
+ The Neomorph SDK provides communication tools for building theme designer interfaces. It enables theme designers to retrieve CSS variable data from target applications and build custom theme customization UIs.
11
+
12
+ ## πŸ—οΈ Architecture
13
+
14
+ ```
15
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
16
+ β”‚ Your Application│←──── Neomorph Bridge ────→│ Theme Designer β”‚
17
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
18
+ β”‚ CSS Variables β”‚ β”‚ Custom UI β”‚
19
+ β”‚ β€’ --primary β”‚ β”‚ β€’ Color Pickers β”‚
20
+ β”‚ β€’ --font-size β”‚ β”‚ β€’ Sliders β”‚
21
+ β”‚ β€’ --border β”‚ β”‚ β€’ Input Fields β”‚
22
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
23
+ ```
24
+
25
+ ## πŸ“¦ Installation
26
+
27
+ ```bash
28
+ npm install @neomorph/sdk
29
+ ```
30
+
31
+ ## πŸš€ Quick Start
32
+
33
+ ### Prerequisites
34
+
35
+ Your application must use CSS custom properties for theming:
36
+
37
+ ```css
38
+ :root {
39
+ --primary-color: #3498db;
40
+ --secondary-color: #2ecc71;
41
+ --background-color: #ffffff;
42
+ --text-color: #333333;
43
+ --border-radius: 4px;
44
+ --font-size-base: 16px;
45
+ }
46
+
47
+ .button {
48
+ background-color: var(--primary-color);
49
+ color: var(--text-color);
50
+ border-radius: var(--border-radius);
51
+ font-size: var(--font-size-base);
52
+ }
53
+ ```
54
+
55
+ ## πŸ“– Use Cases
56
+
57
+ ### Loomer Integration (Theme Designer Side)
58
+
59
+ Use the Loomer class to communicate with applications and retrieve CSS variable data. The SDK provides the data and communication layer - you build the actual theme designer UI based on the returned JSON data.
60
+
61
+ #### Basic Data Retrieval
62
+
63
+ ```typescript
64
+ import { Loomer, type SDKResponse } from '@neomorph/sdk';
65
+
66
+ // Initialize Loomer for theme designer communication
67
+ const loomer = new Loomer();
68
+
69
+ // Load target application in iframe with callback
70
+ loomer.loadApplication('https://your-app.com', (response: SDKResponse | null) => {
71
+ if (response) {
72
+ console.log('Received data:', response);
73
+
74
+ // Actual response structure:
75
+ // {
76
+ // requestId: "randomId",
77
+ // service: "skinweaver",
78
+ // payload: { action: "listenCssVariables", ...cssData }
79
+ // }
80
+
81
+ // YOU process this data and build UI
82
+ buildYourThemeDesigner(response);
83
+ }
84
+ });
85
+
86
+ // Request CSS variables from the loaded application
87
+ function startListening() {
88
+ loomer.listenCssVariables(); // Sends PostMessage to iframe
89
+ }
90
+
91
+ // Example: Build your own theme designer UI
92
+ function buildYourThemeDesigner(response: SDKResponse) {
93
+ // Extract data from the response payload
94
+ const cssData = response.payload;
95
+
96
+ // Create your own UI based on the received data
97
+ // YOU implement the color pickers, sliders, inputs, etc.
98
+ createCustomThemeControls(cssData);
99
+ }
100
+ ```
101
+
102
+ #### Advanced Data Retrieval with Configuration
103
+
104
+ ```typescript
105
+ import { Loomer, type SDKResponse } from '@neomorph/sdk';
106
+
107
+ const loomer = new Loomer({
108
+ // Custom iframe container
109
+ container: document.getElementById('preview-container'),
110
+
111
+ // Communication timeout
112
+ timeout: 5000,
113
+
114
+ // Enable debugging
115
+ debug: true
116
+ });
117
+
118
+ // Load application with error handling
119
+ try {
120
+ await loomer.loadApplication('https://your-app.com', {
121
+ onLoad: () => console.log('Application loaded'),
122
+ onError: (error) => console.error('Load failed:', error),
123
+ onThemeChange: (variables) => console.log('Theme applied:', variables)
124
+ });
125
+
126
+ // Request available CSS variables
127
+ const response = await loomer.getCssVariables();
128
+
129
+ if (response.success) {
130
+ const { cssVariables, metadata } = response.data;
131
+
132
+ // Process and group the JSON data
133
+ const groupedVars = groupVariablesByCategory(cssVariables);
134
+
135
+ // Build your custom theme designer UI with the data
136
+ buildYourThemeDesignerUI(groupedVars);
137
+ }
138
+
139
+ } catch (error) {
140
+ console.error('Integration failed:', error);
141
+ }
142
+
143
+ // Batch update multiple variables
144
+ function applyTheme(theme: Record<string, string>) {
145
+ Object.entries(theme).forEach(([variable, value]) => {
146
+ loomer.updateCssVariable(variable, value);
147
+ });
148
+ }
149
+ ```
150
+
151
+ ## πŸ”’ Security Considerations
152
+
153
+ - **Cross-Origin Communication**: All PostMessage communication includes origin validation
154
+ - **CSS Variable Exposure**: Only explicitly exposed variables are accessible via Weaver
155
+ - **Iframe Sandboxing**: Consider appropriate iframe sandbox attributes for security
156
+ - **Input Validation**: Always validate CSS variable values before applying
157
+
158
+ ## πŸ› Troubleshooting
159
+
160
+ ### Common Issues
161
+
162
+ **PostMessage not working**
163
+ - Ensure both applications are served over HTTPS (or both over HTTP in development)
164
+ - Check that iframe src and parent window origins are correctly configured
165
+ - Verify that Weaver script is loaded before Loomer attempts communication
166
+
167
+ **CSS Variables not detected**
168
+ - Confirm variables are defined in `:root` or explicitly exposed via Weaver options
169
+ - Check browser DevTools for CSS custom property support
170
+ - Ensure variables use the `--` prefix
171
+
172
+ **Cross-origin errors**
173
+ - Verify CORS headers are properly configured on target application
174
+ - Use appropriate iframe sandbox attributes
175
+ - Consider using a proxy for local development
176
+
177
+ ## 🀝 Contributing
178
+
179
+ See the main [repository README](../../README.md) for contribution guidelines.
180
+
181
+ ## πŸ“„ License
182
+
183
+ ISC - See [LICENSE](../../LICENSE) for details.
184
+
185
+ ---
186
+
187
+ **Made with ❀️ by the Neomorph team**
188
+
189
+ For more information, visit the [main repository](https://github.com/sinha-sahil/neomorph).
@@ -0,0 +1,2 @@
1
+ export * from "./loomer";
2
+ export * from "./weaver";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ function e(e){return"string"==typeof e?e:null}function n(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}const t=function(t){if(n(t)){const i=e(t.requestId),r=e(t.service),a=function(e){if(n(e))return{...e};return null}(t.payload);if(null!==i&&null!==r&&null!==a)return{requestId:i,service:r,payload:a}}return null};class i{applicationFrame;constructor(){this.applicationFrame=null}loadApplication(e,n){if("undefined"!=typeof document&&"undefined"!=typeof window)try{this.applicationFrame=document.createElement("iframe"),this.applicationFrame.src=e,this.applicationFrame.style.width="100%",this.applicationFrame.style.height="100%",this.applicationFrame.style.border="none",document.body.appendChild(this.applicationFrame),window.addEventListener("message",e=>{const i=t(e.data);n(i)})}catch(e){console.error("πŸ•ΈοΈ Weaver: Failed to load application:",e)}else console.warn("πŸ•ΈοΈ Weaver: loadApplication() called in non-browser environment")}listenCssVariables(){if("undefined"!=typeof window)try{const e=this.applicationFrame;if(!e?.contentWindow)return void console.error("πŸ•ΈοΈ Weaver: No iframe loaded or iframe not ready");e.contentWindow.postMessage(JSON.stringify({source:"skinweaver",payload:JSON.stringify({requestId:"randomId",service:"skinweaver",payload:{action:"listenCssVariables"}})}),"*")}catch(e){console.error("πŸ•ΈοΈ Weaver: Failed to send message to iframe:",e)}else console.warn("πŸ•ΈοΈ Weaver: listenCssVariables() called in non-browser environment")}}class r{static inject(e="1.0.0"){if("undefined"!=typeof document)try{const n=document.createElement("script");n.src=`https://cdn.jsdelivr.net/gh/sinha-sahil/neomorph/build/weaver/${e}/index.js`,n.type="text/javascript",document.head.appendChild(n)}catch(e){console.error("πŸ•ΈοΈ Weaver: Failed to inject weaver script:",e)}else console.warn("πŸ•ΈοΈ Weaver: inject() called in non-browser environment")}}export{i as Loomer,r as Weaver};
@@ -0,0 +1,7 @@
1
+ import { SDKResponse } from "./types";
2
+ export declare class Loomer {
3
+ private applicationFrame;
4
+ constructor();
5
+ loadApplication(url: string, callback: (response: SDKResponse | null) => void): void;
6
+ listenCssVariables(): void;
7
+ }
@@ -0,0 +1,21 @@
1
+ export type DocumentHost = {
2
+ name: string;
3
+ target: DocumentLike;
4
+ };
5
+ export type DocumentLike = Document | ShadowRoot;
6
+ export type CSSProperty = {
7
+ property: string;
8
+ value: string;
9
+ };
10
+ export type HostStyles = Map<string, Array<CSSProperty>>;
11
+ export type SDKPayload = {
12
+ requestId: string;
13
+ service: string;
14
+ payload: SDKPayloadPayload;
15
+ };
16
+ export type SDKPayloadPayload = Record<string, unknown>;
17
+ export type SDKResponse = SDKPayload;
18
+ export declare function decodeCssProperty(rawInput: unknown): CSSProperty | null;
19
+ export declare function decodeSDKPayload(rawInput: unknown): SDKPayload | null;
20
+ export declare function decodeSDKPayloadPayload(rawInput: unknown): SDKPayloadPayload | null;
21
+ export declare const decodeSDKResponse: (rawInput: unknown) => SDKResponse | null;
@@ -0,0 +1,3 @@
1
+ export declare class Weaver {
2
+ static inject(version?: string): void;
3
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@neomorph/sdk",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "description": "Core SDK for Neomorph - Advanced theme generator toolkit for web applications",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist/",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "dev": "rollup -c rollup.config.js --watch",
20
+ "build": "rollup --config rollup.config.js",
21
+ "format": "npx prettier --write .",
22
+ "lint": "prettier --plugin-search-dir . --check . && eslint .",
23
+ "clean": "rm -rf dist"
24
+ },
25
+ "keywords": [
26
+ "neomorph",
27
+ "theme",
28
+ "css-variables",
29
+ "transformation",
30
+ "ui",
31
+ "design-system",
32
+ "theming",
33
+ "sdk"
34
+ ],
35
+ "author": "Sahil Sinha",
36
+ "license": "ISC",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/sinha-sahil/neomorph.git",
40
+ "directory": "packages/sdk"
41
+ },
42
+ "homepage": "https://github.com/sinha-sahil/neomorph#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/sinha-sahil/neomorph/issues"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "packageManager": "pnpm@10.18.0",
50
+ "dependencies": {
51
+ "type-decoder": "^2.1.0"
52
+ },
53
+ "devDependencies": {
54
+ "@eslint/eslintrc": "^3.3.1",
55
+ "@eslint/js": "^9.36.0",
56
+ "@rollup/plugin-alias": "^5.1.1",
57
+ "@rollup/plugin-commonjs": "^28.0.6",
58
+ "@rollup/plugin-node-resolve": "^16.0.1",
59
+ "@rollup/plugin-terser": "^0.4.4",
60
+ "@rollup/plugin-typescript": "^12.1.4",
61
+ "@typescript-eslint/eslint-plugin": "^8.44.0",
62
+ "@typescript-eslint/parser": "^8.44.0",
63
+ "eslint": "^9.36.0",
64
+ "eslint-config-prettier": "^10.1.8",
65
+ "prettier": "^3.6.2",
66
+ "rollup": "^4.52.0",
67
+ "tslib": "^2.8.1",
68
+ "typescript": "^5.9.2"
69
+ }
70
+ }