@miradorlabs/parallax-web 1.0.7 → 2.0.0

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/SETUP.md DELETED
@@ -1,220 +0,0 @@
1
- # Web Parallax Client Setup Summary
2
-
3
- This document summarizes the complete configuration and structure of the web-parallax-client SDK.
4
-
5
- ## Directory Structure
6
-
7
- ```
8
- web-parallax-client/
9
- ├── dist/ # Build output (generated)
10
- │ ├── index.esm.js # ES Module bundle
11
- │ ├── index.esm.js.map # ESM source map
12
- │ ├── index.umd.js # UMD bundle (browser global)
13
- │ ├── index.umd.js.map # UMD source map
14
- │ └── index.d.ts # TypeScript declarations
15
- ├── src/
16
- │ ├── grpc/
17
- │ │ └── index.ts # GrpcWebRpc adapter (uses Fetch API)
18
- │ ├── parallax/
19
- │ │ └── index.ts # ParallaxClient main class
20
- │ └── helpers/
21
- │ └── index.ts # Serialization helpers
22
- ├── tests/
23
- │ └── parallax.test.ts # Jest unit tests
24
- ├── index.ts # Main entry point
25
- ├── package.json # NPM package configuration
26
- ├── tsconfig.json # TypeScript config (dev)
27
- ├── tsconfig.build.json # TypeScript config (build)
28
- ├── rollup.config.mjs # Rollup bundler configuration
29
- ├── jest.config.ts # Jest test configuration
30
- ├── eslint.config.js # ESLint configuration
31
- ├── .prettierrc # Prettier configuration
32
- ├── .nvmrc # Node version (22.13.0)
33
- ├── .gitignore # Git ignore rules
34
- └── README.md # User documentation
35
- ```
36
-
37
- ## Key Configuration Files
38
-
39
- ### package.json
40
-
41
- - **Name**: `@miradorlabs/parallax-web`
42
- - **Main Entry Points**:
43
- - `main`: `dist/index.umd.js` (UMD for Node.js/CommonJS)
44
- - `module`: `dist/index.esm.js` (ES Module for bundlers)
45
- - `browser`: `dist/index.umd.js` (Browser global)
46
- - `types`: `dist/index.d.ts` (TypeScript definitions)
47
- - **Dependencies**:
48
- - `google-protobuf`: ^4.0.1
49
- - `mirador-gateway-parallax-web`: grpc-web package from GCS
50
- - `rxjs`: ^7.8.2
51
- - **Scripts**:
52
- - `build`: Build all bundles with Rollup
53
- - `test`: Run Jest tests
54
- - `test:watch`: Run Jest in watch mode
55
- - `test:coverage`: Generate coverage report
56
-
57
- ### rollup.config.mjs
58
-
59
- Generates three outputs:
60
-
61
- 1. **ESM Bundle** (`dist/index.esm.js`)
62
- - Format: ES Module
63
- - For modern bundlers (Webpack, Vite, etc.)
64
-
65
- 2. **UMD Bundle** (`dist/index.umd.js`)
66
- - Format: UMD
67
- - Global name: `ParallaxWeb`
68
- - For browser `<script>` tags
69
-
70
- 3. **Type Definitions** (`dist/index.d.ts`)
71
- - TypeScript declarations
72
-
73
- All bundles treat external dependencies as external:
74
- - `google-protobuf`
75
- - `mirador-gateway-parallax-web/*`
76
- - `rxjs/*`
77
-
78
- ### tsconfig.json
79
-
80
- - Target: ES2020
81
- - Module: ESNext (for browser)
82
- - Lib: ES2020, DOM, DOM.Iterable
83
- - Strict mode enabled
84
- - Module resolution: bundler
85
-
86
- ### jest.config.ts
87
-
88
- - Preset: ts-jest
89
- - Test environment: **jsdom** (browser simulation)
90
- - Test match: `**/*.test.ts`
91
- - Coverage from `src/**/*.ts`
92
-
93
- ## Key Differences from nodejs-parallax-client
94
-
95
- | Feature | nodejs-parallax-client | web-parallax-client |
96
- |---------|------------------------|---------------------|
97
- | gRPC Library | `@grpc/grpc-js` | Fetch API (gRPC-Web compatible) |
98
- | Transport | Native gRPC | HTTP/HTTPS with gRPC-Web protocol |
99
- | Environment | Node.js | Browser |
100
- | Module System | CommonJS | ESM + UMD |
101
- | Test Environment | Node | jsdom (browser) |
102
- | Connection | Can use insecure | Always uses HTTPS |
103
- | Default URL | localhost:50053 | https://gateway-parallax-dev... |
104
-
105
- ## Source Files
106
-
107
- ### src/grpc/index.ts - GrpcWebRpc
108
-
109
- Implements the gRPC-Web RPC adapter using browser Fetch API:
110
-
111
- - **Unary requests**: Standard HTTP POST with protobuf binary body
112
- - **Server streaming**: Uses ReadableStream from Response.body
113
- - **Headers**: Includes `Content-Type: application/grpc-web+proto`
114
- - **API Key**: Sent as `x-api-key` header
115
- - **Type casting**: `data.buffer as ArrayBuffer` for Fetch compatibility
116
-
117
- ### src/parallax/index.ts - ParallaxClient
118
-
119
- Main SDK client with methods:
120
- - `createTrace()`: Create a new trace
121
- - `startSpan()`: Start a span within a trace
122
- - `finishSpan()`: Finish a span
123
- - `addSpanAttributes()`: Add attributes to a span
124
- - `addSpanEvent()`: Add an event to a span
125
- - `addSpanError()`: Add an error to a span
126
- - `addSpanHint()`: Add a blockchain transaction hint
127
-
128
- ### tests/parallax.test.ts
129
-
130
- Comprehensive test suite covering:
131
- - Client instantiation
132
- - All SDK methods (success and error cases)
133
- - Integration scenarios
134
- - API key handling
135
- - Mock implementation of GrpcWebRpc
136
-
137
- ## Build Process
138
-
139
- ```bash
140
- npm run build
141
- ```
142
-
143
- 1. Clears `dist/` directory
144
- 2. Runs Rollup with three configurations in parallel:
145
- - ESM bundle with source maps
146
- - UMD bundle with source maps
147
- - TypeScript declarations
148
-
149
- Build warnings about `mirador-gateway-parallax-web` imports are **expected** - these are external dependencies resolved at runtime.
150
-
151
- ## Testing
152
-
153
- ```bash
154
- npm test # Run all tests
155
- npm run test:watch # Watch mode
156
- npm run test:coverage # Generate coverage report
157
- ```
158
-
159
- Tests use:
160
- - **jsdom**: Simulates browser environment
161
- - **ts-jest**: TypeScript transformation
162
- - **Mocking**: GrpcWebRpc is mocked for unit tests
163
-
164
- ## Publishing
165
-
166
- ```bash
167
- npm run release:patch # Bump patch version (1.0.0 -> 1.0.1)
168
- npm run release:minor # Bump minor version (1.0.0 -> 1.1.0)
169
- npm run release:major # Bump major version (1.0.0 -> 2.0.0)
170
- ```
171
-
172
- Versioning automatically:
173
- 1. Updates `package.json` version
174
- 2. Creates git tag
175
- 3. Pushes with `--follow-tags`
176
-
177
- ## Browser Compatibility
178
-
179
- Requires modern browsers supporting:
180
- - ES2020 features
181
- - Fetch API
182
- - Promises
183
- - ReadableStream
184
- - Uint8Array
185
-
186
- For older browsers, polyfills may be needed.
187
-
188
- ## Usage in Browser
189
-
190
- ### Via NPM/Bundler (Recommended)
191
-
192
- ```typescript
193
- import { ParallaxClient } from '@miradorlabs/parallax-web';
194
-
195
- const client = new ParallaxClient('your-api-key');
196
- ```
197
-
198
- ### Via UMD Script Tag
199
-
200
- ```html
201
- <script src="node_modules/@miradorlabs/parallax-web/dist/index.umd.js"></script>
202
- <script>
203
- const client = new ParallaxWeb.ParallaxClient('your-api-key');
204
- </script>
205
- ```
206
-
207
- ## Next Steps
208
-
209
- 1. **Install dependencies**: Already done (`npm install`)
210
- 2. **Build**: Already done (`npm run build`)
211
- 3. **Test**: Run `npm test` to verify all tests pass
212
- 4. **Customize**: Update `GRPC_GATEWAY_API_URL` in `src/parallax/index.ts` if needed
213
- 5. **Publish**: When ready, use `npm run release:patch` to version and publish
214
-
215
- ## Notes
216
-
217
- - The package uses the grpc-web package from GCS: `mirador-gateway-parallax-grpc-web-1.0.9.tgz`
218
- - Type warnings during build about missing type declarations are expected for external packages
219
- - All gRPC-Web requests use the browser's Fetch API, making this SDK compatible with modern web applications
220
- - The SDK maintains the same API surface as the Node.js client for consistency
package/src/grpc/index.ts DELETED
@@ -1,155 +0,0 @@
1
- import { Observable } from "rxjs";
2
-
3
- interface Metadata {
4
- [key: string]: string;
5
- }
6
-
7
- interface Rpc {
8
- request(
9
- service: string,
10
- method: string,
11
- data: Uint8Array,
12
- metadata?: Metadata
13
- ): Promise<Uint8Array>;
14
- clientStreamingRequest(
15
- service: string,
16
- method: string,
17
- data: Observable<Uint8Array>
18
- ): Promise<Uint8Array>;
19
- serverStreamingRequest(
20
- service: string,
21
- method: string,
22
- data: Uint8Array
23
- ): Observable<Uint8Array>;
24
- bidirectionalStreamingRequest(
25
- service: string,
26
- method: string,
27
- data: Observable<Uint8Array>
28
- ): Observable<Uint8Array>;
29
- }
30
-
31
- export class GrpcWebRpc implements Rpc {
32
- private url: string;
33
- private apiKey?: string;
34
-
35
- constructor(url: string, apiKey?: string) {
36
- this.url = url;
37
- this.apiKey = apiKey;
38
- }
39
-
40
- async request(
41
- service: string,
42
- method: string,
43
- data: Uint8Array,
44
- metadata?: Metadata
45
- ): Promise<Uint8Array> {
46
- console.log(`[gRPC-Web] Making request to ${this.url}/${service}/${method}`);
47
-
48
- const headers: HeadersInit = {
49
- 'Content-Type': 'application/grpc-web+proto',
50
- 'X-Grpc-Web': '1',
51
- };
52
-
53
- // Add API key to headers if provided
54
- if (this.apiKey) {
55
- headers['x-api-key'] = this.apiKey;
56
- }
57
-
58
- // Add custom metadata
59
- if (metadata) {
60
- Object.entries(metadata).forEach(([key, value]) => {
61
- headers[key] = value;
62
- });
63
- }
64
-
65
- try {
66
- const response = await fetch(`${this.url}/${service}/${method}`, {
67
- method: 'POST',
68
- headers,
69
- body: data.buffer as ArrayBuffer,
70
- });
71
-
72
- if (!response.ok) {
73
- const errorText = await response.text();
74
- throw new Error(`gRPC-Web error: ${response.status} ${response.statusText} - ${errorText}`);
75
- }
76
-
77
- const arrayBuffer = await response.arrayBuffer();
78
- console.log(`[gRPC-Web] Success from ${this.url}/${service}/${method}`);
79
- return new Uint8Array(arrayBuffer);
80
- } catch (error) {
81
- console.error(
82
- `[gRPC-Web] Error from ${this.url}/${service}/${method}:`,
83
- error instanceof Error ? error.message : String(error)
84
- );
85
- throw error;
86
- }
87
- }
88
-
89
- clientStreamingRequest(): Promise<Uint8Array> {
90
- throw new Error("Client streaming not yet implemented for gRPC-Web");
91
- }
92
-
93
- serverStreamingRequest(
94
- service: string,
95
- method: string,
96
- data: Uint8Array
97
- ): Observable<Uint8Array> {
98
- return new Observable((subscriber) => {
99
- const headers: HeadersInit = {
100
- 'Content-Type': 'application/grpc-web+proto',
101
- 'X-Grpc-Web': '1',
102
- };
103
-
104
- // Add API key to headers if provided
105
- if (this.apiKey) {
106
- headers['x-api-key'] = this.apiKey;
107
- }
108
-
109
- fetch(`${this.url}/${service}/${method}`, {
110
- method: 'POST',
111
- headers,
112
- body: data.buffer as ArrayBuffer,
113
- })
114
- .then(async (response) => {
115
- if (!response.ok) {
116
- throw new Error(`gRPC-Web error: ${response.status} ${response.statusText}`);
117
- }
118
-
119
- if (!response.body) {
120
- throw new Error('Response body is null');
121
- }
122
-
123
- const reader = response.body.getReader();
124
-
125
- try {
126
- while (true) {
127
- const { done, value } = await reader.read();
128
-
129
- if (done) {
130
- subscriber.complete();
131
- break;
132
- }
133
-
134
- if (value) {
135
- subscriber.next(value);
136
- }
137
- }
138
- } catch (error) {
139
- subscriber.error(error);
140
- }
141
- })
142
- .catch((error) => {
143
- subscriber.error(error);
144
- });
145
-
146
- return () => {
147
- // Cleanup logic if needed
148
- };
149
- });
150
- }
151
-
152
- bidirectionalStreamingRequest(): Observable<Uint8Array> {
153
- throw new Error("Bidirectional streaming not yet implemented for gRPC-Web");
154
- }
155
- }
@@ -1,13 +0,0 @@
1
- // Helper serialization functions for browser environment
2
- function serialize(value: Uint8Array): Uint8Array {
3
- return value;
4
- }
5
-
6
- function deserialize(bytes: Uint8Array): Uint8Array {
7
- return bytes;
8
- }
9
-
10
- export {
11
- deserialize,
12
- serialize
13
- }
@@ -1,296 +0,0 @@
1
- /**
2
- * Parallax Service - Transaction Tracing for Web Applications
3
- * Creates individual traces for each transaction and tracks them through their lifecycle
4
- *
5
- * This service provides a simplified interface for tracking transactions with automatic
6
- * client metadata collection and lifecycle management.
7
- */
8
-
9
- import { ParallaxClient } from './index';
10
- import type {
11
- CreateTraceResponse,
12
- } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
13
-
14
- interface TransactionInfo {
15
- traceId: string;
16
- timestamp: string;
17
- txHash: string | null;
18
- from?: string;
19
- to?: string;
20
- network?: string;
21
- }
22
-
23
- interface TransactionData {
24
- from: string;
25
- to: string;
26
- value: string;
27
- network?: string;
28
- walletAddress?: string;
29
- additionalData?: Record<string, any>;
30
- }
31
-
32
- interface FinishOptions {
33
- success: boolean;
34
- error?: string;
35
- }
36
-
37
- export class ParallaxService {
38
- private client: ParallaxClient | null = null;
39
- private activeTransactions: Map<string, TransactionInfo> = new Map();
40
-
41
- constructor() {
42
- // Client will be initialized lazily
43
- }
44
-
45
- /**
46
- * Initialize the Parallax client (lazy initialization)
47
- * @param apiKey - Optional API key for authentication
48
- * @param gatewayUrl - Optional custom gateway URL
49
- */
50
- private _ensureClient(apiKey?: string, gatewayUrl?: string): void {
51
- if (this.client) return;
52
-
53
- // Determine gateway URL based on environment if not provided
54
- let url = gatewayUrl;
55
- if (!url && typeof window !== 'undefined') {
56
- const isDevelopment =
57
- window.location.hostname === 'localhost' ||
58
- window.location.hostname === '127.0.0.1';
59
-
60
- url = isDevelopment
61
- ? `${window.location.protocol}//${window.location.host}/parallax-gateway`
62
- : 'https://gateway-parallax-dev.mirador.org';
63
- }
64
-
65
- this.client = new ParallaxClient(apiKey || '', url);
66
- console.log('[ParallaxService] Client initialized with URL:', url);
67
- }
68
-
69
- /**
70
- * Start a new transaction trace
71
- * Called when user initiates a transaction
72
- *
73
- * Uses the builder pattern to create a trace with events
74
- *
75
- * @param txData - Transaction data
76
- * @param name - Name for the trace (e.g., 'SendingTrace', 'SwappingTrace')
77
- * @param options - Optional configuration (apiKey, gatewayUrl, includeClientMeta)
78
- * @returns Promise with traceId, rootSpanId, and txId
79
- */
80
- async startTransactionTrace(
81
- txData: TransactionData,
82
- name: string = 'WalletTransaction',
83
- options?: { apiKey?: string; gatewayUrl?: string; includeClientMeta?: boolean }
84
- ): Promise<{ traceId: string; rootSpanId: string; txId: string }> {
85
- this._ensureClient(options?.apiKey, options?.gatewayUrl);
86
-
87
- if (!this.client) {
88
- throw new Error('Failed to initialize Parallax client');
89
- }
90
-
91
- try {
92
- const txId = `tx_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
93
- const timestamp = new Date();
94
-
95
- // Build the trace using the builder pattern
96
- const builder = this.client
97
- .trace(name, options?.includeClientMeta ?? true)
98
- .addAttribute('transactionId', txId)
99
- .addAttribute('walletAddress', txData.walletAddress || txData.from)
100
- .addAttribute('network', txData.network || 'Unknown')
101
- .addAttribute('transactionStart', timestamp.toISOString())
102
- .addAttribute('from', txData.from)
103
- .addAttribute('to', txData.to)
104
- .addAttribute('value', txData.value)
105
- .addTags(['transaction', 'wallet', txData.network || 'unknown'])
106
- .addEvent('transaction_initiated', {
107
- from: txData.from,
108
- to: txData.to,
109
- value: txData.value,
110
- timestamp: timestamp.toISOString(),
111
- });
112
-
113
- // Add any additional transaction data as attributes
114
- if (txData.additionalData) {
115
- Object.entries(txData.additionalData).forEach(([key, value]) => {
116
- builder.addAttribute(key, typeof value === 'object' ? JSON.stringify(value) : String(value));
117
- });
118
- }
119
-
120
- // Submit the trace
121
- const traceResponse: CreateTraceResponse = await builder.submit();
122
- const traceId = traceResponse.getTraceId();
123
-
124
- // Store transaction info
125
- this.activeTransactions.set(txId, {
126
- traceId,
127
- timestamp: timestamp.toISOString(),
128
- txHash: null,
129
- from: txData.from,
130
- to: txData.to,
131
- network: txData.network,
132
- });
133
-
134
- console.log('[ParallaxService] Transaction trace started:', {
135
- txId,
136
- traceId,
137
- from: txData.from,
138
- to: txData.to,
139
- });
140
-
141
- return { traceId, rootSpanId: traceId, txId };
142
- } catch (error) {
143
- console.error('[ParallaxService] Failed to start transaction trace:', error);
144
- throw error;
145
- }
146
- }
147
-
148
- /**
149
- * Associate a transaction hash with an existing trace
150
- * Called when the transaction hash is available after signing/sending
151
- *
152
- * NOTE: This method is deprecated as the new API does not support adding hints to existing traces.
153
- * Transaction hashes should be provided at trace creation time via the builder's submit(txHash, chainId) method.
154
- *
155
- * @param txId - Transaction identifier returned from startTransactionTrace
156
- * @param txHash - Blockchain transaction hash
157
- * @param chainId - Chain ID
158
- * @deprecated Use submit(txHash, chainId) when creating the trace instead
159
- */
160
- async associateTransactionHash(txId: string, txHash: string, chainId: number): Promise<void> {
161
- const txInfo = this.activeTransactions.get(txId);
162
- if (!txInfo) {
163
- console.warn(`[ParallaxService] Transaction ${txId} not found in active transactions`);
164
- return;
165
- }
166
-
167
- // Update stored tx info
168
- txInfo.txHash = txHash;
169
- this.activeTransactions.set(txId, txInfo);
170
-
171
- console.warn('[ParallaxService] associateTransactionHash is deprecated. The new API does not support adding transaction hashes after trace creation. Please provide the txHash when creating the trace using submit(txHash, chainId).');
172
- console.log('[ParallaxService] Transaction hash updated in local cache:', {
173
- txId,
174
- txHash,
175
- traceId: txInfo.traceId,
176
- });
177
- }
178
-
179
- /**
180
- * Add an event to a transaction trace
181
- *
182
- * NOTE: This method is deprecated as the new API does not support adding events to existing traces.
183
- * Events should be added to the trace builder before calling submit().
184
- *
185
- * @param txId - Transaction identifier
186
- * @param eventName - Event name
187
- * @param attributes - Event attributes
188
- * @deprecated Use the trace builder's addEvent() method before calling submit() instead
189
- */
190
- async addTransactionEvent(
191
- txId: string,
192
- eventName: string,
193
- attributes: Record<string, any> = {}
194
- ): Promise<void> {
195
- const txInfo = this.activeTransactions.get(txId);
196
- if (!txInfo) {
197
- console.warn(`[ParallaxService] Transaction ${txId} not found. Cannot add event '${eventName}'`);
198
- return;
199
- }
200
-
201
- console.warn('[ParallaxService] addTransactionEvent is deprecated. The new API does not support adding events after trace creation. Events should be added using the builder pattern before calling submit().');
202
- }
203
-
204
- /**
205
- * Add an error to a transaction trace
206
- *
207
- * NOTE: This method is deprecated as the new API does not support adding errors to existing traces.
208
- * Errors should be added as events to the trace builder before calling submit().
209
- *
210
- * @param txId - Transaction identifier
211
- * @param error - Error object or message
212
- * @param errorType - Type/category of error (e.g., 'TransactionError', 'NetworkError', 'UserRejection')
213
- * @deprecated Use the trace builder's addEvent() method to add error events before calling submit() instead
214
- */
215
- async addTransactionError(
216
- txId: string,
217
- error: Error | string,
218
- errorType: string = 'TransactionError'
219
- ): Promise<void> {
220
- const txInfo = this.activeTransactions.get(txId);
221
- if (!txInfo) {
222
- console.warn(`[ParallaxService] Transaction ${txId} not found. Cannot add error.`);
223
- return;
224
- }
225
-
226
- console.warn('[ParallaxService] addTransactionError is deprecated. The new API does not support adding errors after trace creation. Add error events using the builder pattern before calling submit().');
227
- }
228
-
229
- /**
230
- * Finish a transaction trace
231
- *
232
- * NOTE: This method is deprecated as the new API does not support span lifecycle management.
233
- * Traces are completed when submit() is called on the builder.
234
- *
235
- * @param txId - Transaction identifier
236
- * @param options - Finish options (success, error message)
237
- * @deprecated Traces are automatically completed when submit() is called
238
- */
239
- async finishTransactionTrace(txId: string, options: FinishOptions = { success: true }): Promise<void> {
240
- const txInfo = this.activeTransactions.get(txId);
241
- if (!txInfo) {
242
- console.warn(`[ParallaxService] Transaction ${txId} not found. Cannot finish.`);
243
- return;
244
- }
245
-
246
- console.warn('[ParallaxService] finishTransactionTrace is deprecated. The new API does not support span lifecycle. Traces are completed when submit() is called.');
247
-
248
- console.log('[ParallaxService] Transaction trace marked as finished (local only):', {
249
- txId,
250
- traceId: txInfo.traceId,
251
- success: options.success,
252
- txHash: txInfo.txHash,
253
- });
254
-
255
- // Remove from active transactions
256
- this.activeTransactions.delete(txId);
257
- }
258
-
259
- /**
260
- * Get info about an active transaction
261
- *
262
- * @param txId - Transaction identifier
263
- * @returns Transaction info or null if not found
264
- */
265
- getTransactionInfo(txId: string): TransactionInfo | null {
266
- return this.activeTransactions.get(txId) || null;
267
- }
268
-
269
- /**
270
- * Get all active transactions
271
- *
272
- * @returns Array of active transaction info
273
- */
274
- getAllActiveTransactions(): Array<TransactionInfo & { txId: string }> {
275
- return Array.from(this.activeTransactions.entries()).map(([txId, info]) => ({
276
- txId,
277
- ...info,
278
- }));
279
- }
280
-
281
- /**
282
- * Get the ParallaxClient instance for advanced usage
283
- * @param apiKey - Optional API key
284
- * @param gatewayUrl - Optional gateway URL
285
- */
286
- getClient(apiKey?: string, gatewayUrl?: string): ParallaxClient {
287
- this._ensureClient(apiKey, gatewayUrl);
288
- if (!this.client) {
289
- throw new Error('Failed to initialize Parallax client');
290
- }
291
- return this.client;
292
- }
293
- }
294
-
295
- // Export singleton instance
296
- export const parallaxService = new ParallaxService();