brick-module 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,175 @@
1
+ /**
2
+ * Brick Module Framework - Main API
3
+ * Type-safe access to native modules with automatic code generation
4
+ */
5
+
6
+ import type { TurboModule } from "react-native";
7
+ import { TurboModuleRegistry, NativeEventEmitter } from "react-native";
8
+
9
+ /**
10
+ * Base interface that all Brick module specs must extend
11
+ */
12
+ export interface BrickModuleInterface extends TurboModule {
13
+ readonly moduleName: string;
14
+ readonly supportedEvents?: readonly string[];
15
+ }
16
+
17
+ /**
18
+ * Type alias for module specifications
19
+ * Use this as the base interface when defining your module specs
20
+ * @example
21
+ * export interface MyModuleSpec extends BrickModuleSpec {
22
+ * readonly moduleName: "MyModule";
23
+ * readonly supportedEvents: ["eventA", "eventB"];
24
+ * myMethod(param: string): Promise<string>;
25
+ * }
26
+ */
27
+ export type BrickModuleSpec = BrickModuleInterface;
28
+
29
+ // Module-level state (previously static class members)
30
+ const moduleCache = new Map<string, any>();
31
+ let nativeModule: any = null;
32
+ let eventEmitter: NativeEventEmitter | null = null;
33
+
34
+ /**
35
+ * Gets the native TurboModule instance
36
+ * @private
37
+ */
38
+ function getNativeModule() {
39
+ if (!nativeModule) {
40
+ nativeModule = TurboModuleRegistry.getEnforcing("BrickModule");
41
+ }
42
+ return nativeModule;
43
+ }
44
+
45
+ function getEventEmitter() {
46
+ if (!eventEmitter) {
47
+ const nativeModuleInstance = getNativeModule();
48
+ eventEmitter = new NativeEventEmitter(nativeModuleInstance);
49
+ console.log("eventEmitter", eventEmitter);
50
+ }
51
+ return eventEmitter;
52
+ }
53
+
54
+ /**
55
+ * Enhanced typed module interface with event listeners
56
+ */
57
+ export type BrickModuleWithEvents<T extends BrickModuleInterface> = T & {
58
+ /**
59
+ * Adds a type-safe event listener for this module
60
+ * @param eventName - One of the supported events defined in the module spec
61
+ * @param listener - Callback function to handle the event
62
+ * @returns Unsubscription function to remove the listener
63
+ */
64
+ addEventListener<TEvent = unknown>(
65
+ eventName: T["supportedEvents"] extends readonly (infer U)[] ? U : never,
66
+ listener: (event: TEvent) => void
67
+ ): () => void;
68
+ };
69
+
70
+ /**
71
+ * Gets a typed module instance by name with explicit type parameter
72
+ * @param moduleName - The exact name of the module as defined in its spec
73
+ * @returns Typed module interface with all methods, constants, and event listeners
74
+ */
75
+ function get<T extends BrickModuleInterface>(
76
+ moduleName: string
77
+ ): BrickModuleWithEvents<T> {
78
+ // Check cache first
79
+ const cacheKey = moduleName;
80
+ if (moduleCache.has(cacheKey)) {
81
+ return moduleCache.get(cacheKey);
82
+ }
83
+
84
+ const nativeModuleInstance = getNativeModule();
85
+
86
+ // Create a proxy that intercepts method calls and forwards them to the native module
87
+ const moduleProxy = new Proxy({} as BrickModuleWithEvents<T>, {
88
+ get: (_target, property: string | symbol) => {
89
+ if (typeof property !== "string") {
90
+ return undefined;
91
+ }
92
+
93
+ // Handle event listener methods
94
+ if (property === "addEventListener") {
95
+ return (eventName: string, listener: (event: unknown) => void) => {
96
+ const emitter = getEventEmitter();
97
+ const subscription = emitter.addListener(
98
+ `${moduleName}_${eventName}`,
99
+ listener
100
+ );
101
+
102
+ return () => {
103
+ subscription.remove();
104
+ };
105
+ };
106
+ }
107
+
108
+ // Handle individual constants - check if this property exists as a constant
109
+ const allConstants = nativeModuleInstance?.getConstants?.() ?? {};
110
+ const constantKey = `${moduleName}_${property}`;
111
+ if (constantKey in allConstants) {
112
+ return allConstants[constantKey];
113
+ }
114
+
115
+ // Handle method calls
116
+ return (...args: any[]) => {
117
+ const methodKey = `${moduleName}_${property}`;
118
+
119
+ // Try direct method call first (generated by codegen)
120
+ if (typeof nativeModuleInstance[methodKey] === "function") {
121
+ return nativeModuleInstance[methodKey](...args);
122
+ }
123
+
124
+ throw new Error(`Method ${methodKey} not found`);
125
+ };
126
+ },
127
+
128
+ has: (_target, property) => {
129
+ return typeof property === "string";
130
+ },
131
+
132
+ ownKeys: (_target) => {
133
+ // Return empty array since we're proxying all property access
134
+ return [];
135
+ },
136
+ });
137
+
138
+ // Cache the proxy
139
+ moduleCache.set(cacheKey, moduleProxy);
140
+ return moduleProxy;
141
+ }
142
+
143
+ /**
144
+ * Gets list of all registered modules
145
+ * @returns Promise resolving to array of module names
146
+ */
147
+ function getRegisteredModules(): string[] {
148
+ const nativeModuleInstance = getNativeModule();
149
+ return nativeModuleInstance?.getRegisteredModules() ?? [];
150
+ }
151
+
152
+ /**
153
+ * Clears the module cache (useful for testing or hot reloading)
154
+ * @internal
155
+ */
156
+ function clearCache(): void {
157
+ moduleCache.clear();
158
+ }
159
+
160
+ /**
161
+ * Main Brick Module API object
162
+ * Provides type-safe access to native modules
163
+ */
164
+ export const BrickModule = {
165
+ get,
166
+ getRegisteredModules,
167
+ clearCache,
168
+ } as const;
169
+
170
+ /**
171
+ * Default export for convenience
172
+ */
173
+ export default BrickModule;
174
+
175
+ // Re-export types handled by main index.ts
package/src/index.ts ADDED
@@ -0,0 +1,37 @@
1
+ // Brick Module Framework - Core Library
2
+ // This file provides TypeScript type definitions for the Swift DSL
3
+
4
+ export type { BrickModuleInterface, BrickModuleSpec } from "./BrickModule";
5
+ // Main API exports
6
+ export { default as BrickModule } from "./BrickModule";
7
+ /**
8
+ * Error types for Brick modules
9
+ */
10
+ export class BrickModuleError extends Error {
11
+ constructor(
12
+ message: string,
13
+ public code: string = "GRANITE_ERROR",
14
+ public moduleName?: string,
15
+ public methodName?: string
16
+ ) {
17
+ super(message);
18
+ this.name = "BrickModuleError";
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Configuration interface for brick-codegen
24
+ */
25
+ export interface BrickCodegenConfig {
26
+ outputIos?: string;
27
+ outputAndroid?: string;
28
+ cacheDir?: string;
29
+ incremental?: boolean;
30
+ watch?: boolean;
31
+ excludeModules?: string[];
32
+ typeCheck?: boolean;
33
+ verbose?: boolean;
34
+ newArchOnly?: boolean;
35
+ oldArchOnly?: boolean;
36
+ dev?: boolean;
37
+ }