@roughapp/feature 0.4.1 → 0.5.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/README.md CHANGED
@@ -10,7 +10,8 @@ declarations and a separate stylesheet.
10
10
 
11
11
  > **Pre-1.0:** minor releases may contain breaking changes. Pin
12
12
  > `@roughapp/feature` to an exact version if you want to control when you
13
- > upgrade. See the [changelog](./CHANGELOG.md) before updating.
13
+ > upgrade. Review the hosted [Feature SDK changelog](https://rough.app/docs/changelog)
14
+ > before updating.
14
15
 
15
16
  ## Before you start
16
17
 
@@ -130,7 +131,6 @@ export const roughClient = createRoughClient({
130
131
  const { token } = (await response.json()) as { token: string }
131
132
  return token
132
133
  },
133
- // baseUrl is optional. Omit it when using the Rough production API.
134
134
  })
135
135
  ```
136
136
 
@@ -147,24 +147,45 @@ await whenRoughClientReady({ client: roughClient })
147
147
  A failed client is not restarted. Destroy it and create a new one after the
148
148
  underlying problem has been handled.
149
149
 
150
- ### 3. Render the surface
150
+ ### 3. Subscribe and render feature frames
151
151
 
152
- Importing `@roughapp/feature` registers its custom elements. Set the `client`
153
- and `surface` properties on `<rough-surface>`; these are JavaScript values, not
152
+ The SDK supplies published feature metadata; your app chooses where and how to
153
+ render each frame. Subscribe with `getRoughFeatures()`, then render a
154
+ `<rough-feature>` for every feature with a `publishedSpriteBuildId`. Its
155
+ `client`, `surface`, `featureId`, and `buildId` are JavaScript properties, not
154
156
  HTML attributes.
155
157
 
156
158
  ```ts
157
159
  import '@roughapp/feature'
160
+ import { getRoughFeatures } from '@roughapp/feature'
158
161
 
159
- const element = document.createElement('rough-surface')
160
- element.client = roughClient
161
- element.surface = inboxSurface
162
+ const slot = document.querySelector('#rough-slot')
163
+ const subscription = getRoughFeatures({
164
+ client: roughClient,
165
+ surface: inboxSurface,
166
+ onFeatures: (features) => {
167
+ slot?.replaceChildren(
168
+ ...features.flatMap((feature) => {
169
+ if (!feature.publishedSpriteBuildId) return []
170
+
171
+ const frame = document.createElement('rough-feature')
172
+ frame.client = roughClient
173
+ frame.surface = inboxSurface
174
+ frame.featureId = feature.id
175
+ frame.buildId = feature.publishedSpriteBuildId
176
+ return [frame]
177
+ }),
178
+ )
179
+ },
180
+ onError: (error) => console.error('Unable to load Rough Features', error),
181
+ })
162
182
 
163
- document.querySelector('#rough-slot')?.append(element)
183
+ // During route teardown:
184
+ await subscription.unsubscribe()
164
185
  ```
165
186
 
166
- The package also exports `RoughSurface` for Svelte apps. As with the custom
167
- element, import and render it only on the client when the app uses SSR.
187
+ `RoughFeature` is also exported for Svelte apps. Import and render it only on
188
+ the client when the app uses SSR.
168
189
 
169
190
  ## Open the Feature Builder
170
191
 
@@ -191,8 +212,8 @@ The user can also close the modal from the UI. Calling `close()` again is safe.
191
212
  ## Subscribe to published features
192
213
 
193
214
  Use `getRoughFeatures()` when you need the feature list rather than the rendered
194
- `<rough-surface>`. The callback runs with the initial list, even when it is
195
- empty, and runs again as published features change.
215
+ a rendered feature frame. The callback runs with the initial list, even when
216
+ it is empty, and runs again as published features change.
196
217
 
197
218
  ```ts
198
219
  import { getRoughFeatures } from '@roughapp/feature'
@@ -271,12 +292,12 @@ inherits them.
271
292
  The recommended integration surface is:
272
293
 
273
294
  - `createRoughClient`, `whenRoughClientReady` and the `RoughClient`,
274
- `RoughClientOptions` types;
295
+ `RoughClientOptions` types.
275
296
  - `defineRoughSurface` and the `RoughSurfaceDefinition` type;
276
297
  - `getRoughFeatures` and the `GetRoughFeaturesOptions`,
277
298
  `RoughFeatureSubscription` types;
278
299
  - `openRoughCreate` and the `OpenRoughCreateOptions`, `RoughModalHandle` types;
279
- - `RoughSurface` / `<rough-surface>`;
300
+ - `RoughFeature` / `<rough-feature>` for rendering each published feature;
280
301
  - `Query`, `Mutation`, `Subscription`; and
281
302
  - `RoughClientDestroyedError`, `RoughReplicacheIdentityConflictError`,
282
303
  `RoughSurfaceContractConflictError`, `RoughClientDestroyError` and
@@ -286,9 +307,9 @@ The package also exports lower-level components and data types used to build its
286
307
  own UI. During the pre-1.0 series, do not treat these as a stable integration
287
308
  surface:
288
309
 
289
- - `RoughCreateModal` (`<rough-create-modal>`), `RoughEditButton`
290
- (`<rough-edit-button>`) and `RoughFeature` (`<rough-feature>`). The
291
- `<rough-edit-modal>` element is registered transitively.
310
+ - `RoughCreateModal` (`<rough-create-modal>`) and `RoughEditButton`
311
+ (`<rough-edit-button>`). The `<rough-edit-modal>` element is registered
312
+ transitively.
292
313
  - `PrimaryButton`, `SecondaryButton`, `ResizeHandle`, `SpriteBuildMenu` and
293
314
  `SpriteFrame`.
294
315
  - `Sprite`, `SpriteBuild`, `JsonValue`, `RoughCleanup`, `FetchUserTokenFn`,
package/index.d.ts CHANGED
@@ -343,6 +343,12 @@ type FetchUserTokenFn = () => string | Promise<string>;
343
343
  type RoughClientOptions = {
344
344
  projectId: string;
345
345
  baseUrl?: string;
346
+ /**
347
+ * Origin for uploaded media and Cloudflare image transformations. Defaults to
348
+ * Rough's production media server; set this when using a custom Gateway or
349
+ * media deployment.
350
+ */
351
+ mediaBaseUrl?: string;
346
352
  fetchUserToken: FetchUserTokenFn;
347
353
  };
348
354
  /**
@@ -474,11 +480,11 @@ type RoughModalHandle = {
474
480
  };
475
481
  /**
476
482
  * Opens the Feature Builder for a surface. Resolves the surface itself, so no
477
- * `<RoughSurface>` need be mounted first.
483
+ * feature frame need be mounted first.
478
484
  */
479
485
  declare const openRoughCreate: (options: OpenRoughCreateOptions) => Promise<RoughModalHandle>;
480
486
 
481
- type Props$9 = {
487
+ type Props$8 = {
482
488
  children?: Snippet;
483
489
  class?: string;
484
490
  type?: 'button' | 'submit' | 'reset';
@@ -492,7 +498,7 @@ type Props$9 = {
492
498
  'aria-haspopup'?: boolean | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog';
493
499
  'aria-expanded'?: boolean;
494
500
  };
495
- declare const PrimaryButton: svelte.Component<Props$9, {}, "">;
501
+ declare const PrimaryButton: svelte.Component<Props$8, {}, "">;
496
502
  type PrimaryButton = ReturnType<typeof PrimaryButton>;
497
503
 
498
504
  type ResizableHandle = {
@@ -509,15 +515,15 @@ type ResizableHandle = {
509
515
  destroy: (node: HTMLElement) => void;
510
516
  };
511
517
 
512
- type Props$8 = {
518
+ type Props$7 = {
513
519
  handle: ResizableHandle;
514
520
  children?: Snippet;
515
521
  class?: string;
516
522
  };
517
- declare const ResizeHandle: svelte.Component<Props$8, {}, "">;
523
+ declare const ResizeHandle: svelte.Component<Props$7, {}, "">;
518
524
  type ResizeHandle = ReturnType<typeof ResizeHandle>;
519
525
 
520
- type Props$7 = {
526
+ type Props$6 = {
521
527
  client: RoughClient;
522
528
  surface: RoughSurfaceDefinition;
523
529
  surfaceId: SurfaceId;
@@ -525,16 +531,16 @@ type Props$7 = {
525
531
  portalTarget?: HTMLElement;
526
532
  onclose?: () => void;
527
533
  };
528
- declare const RoughCreateModal: svelte.Component<Props$7, {}, "">;
534
+ declare const RoughCreateModal: svelte.Component<Props$6, {}, "">;
529
535
  type RoughCreateModal = ReturnType<typeof RoughCreateModal>;
530
536
 
531
- type Props$6 = {
537
+ type Props$5 = {
532
538
  client: RoughClient;
533
539
  surface: RoughSurfaceDefinition;
534
540
  spriteId: SpriteId;
535
541
  label?: string;
536
542
  };
537
- declare const RoughEditButton: svelte.Component<Props$6, {}, "">;
543
+ declare const RoughEditButton: svelte.Component<Props$5, {}, "">;
538
544
  type RoughEditButton = ReturnType<typeof RoughEditButton>;
539
545
 
540
546
  type JsonValue = null | boolean | number | string | JsonValue[] | {
@@ -550,24 +556,17 @@ type SpriteFrameDatastoreContext = {
550
556
  spriteInstanceId: string;
551
557
  };
552
558
 
553
- type Props$5 = {
559
+ type Props$4 = {
554
560
  client: RoughClient;
555
561
  surface: RoughSurfaceDefinition;
556
562
  featureId: SpriteId;
557
563
  buildId: SpriteBuildId;
558
564
  datastore?: SpriteFrameDatastore;
565
+ isEditable?: boolean;
559
566
  };
560
- declare const RoughFeature: svelte.Component<Props$5, {}, "">;
567
+ declare const RoughFeature: svelte.Component<Props$4, {}, "">;
561
568
  type RoughFeature = ReturnType<typeof RoughFeature>;
562
569
 
563
- type Props$4 = {
564
- client: RoughClient;
565
- surface: RoughSurfaceDefinition;
566
- getDatastore?: (context: SpriteFrameDatastoreContext) => SpriteFrameDatastore | undefined;
567
- };
568
- declare const RoughSurface: svelte.Component<Props$4, {}, "">;
569
- type RoughSurface = ReturnType<typeof RoughSurface>;
570
-
571
570
  type Props$3 = {
572
571
  children?: Snippet;
573
572
  class?: string;
@@ -636,14 +635,12 @@ type RoughEditModal = ReturnType<typeof RoughEditModal>;
636
635
  * components.
637
636
  */
638
637
 
639
- type RoughSurfaceElement = HTMLElement & ComponentProps<typeof RoughSurface>;
640
638
  type RoughCreateModalElement = HTMLElement & ComponentProps<typeof RoughCreateModal>;
641
639
  type RoughEditModalElement = HTMLElement & ComponentProps<typeof RoughEditModal>;
642
640
  type RoughEditButtonElement = HTMLElement & ComponentProps<typeof RoughEditButton>;
643
641
  type RoughFeatureElement = HTMLElement & ComponentProps<typeof RoughFeature>;
644
642
  declare global {
645
643
  interface HTMLElementTagNameMap {
646
- 'rough-surface': RoughSurfaceElement;
647
644
  'rough-create-modal': RoughCreateModalElement;
648
645
  'rough-edit-modal': RoughEditModalElement;
649
646
  'rough-edit-button': RoughEditButtonElement;
@@ -651,5 +648,5 @@ declare global {
651
648
  }
652
649
  }
653
650
 
654
- export { Mutation, PrimaryButton, Query, ResizeHandle, RoughClientDestroyError, RoughClientDestroyedError, RoughCreateModal, RoughEditButton, RoughFeature, RoughInvalidClientError, RoughReplicacheIdentityConflictError, RoughSurface, RoughSurfaceContractConflictError, SecondaryButton, SpriteBuildMenu, SpriteFrame, Subscription, createRoughClient, defineRoughSurface, getRoughFeatures, openRoughCreate, whenRoughClientReady };
655
- export type { FetchUserTokenFn, GetRoughFeaturesOptions, JsonValue, OpenRoughCreateOptions, RoughCleanup, RoughClient, RoughClientOptions, RoughCreateModalElement, RoughEditButtonElement, RoughEditModalElement, RoughFeatureElement, RoughFeatureSubscription, RoughModalHandle, RoughSurfaceDefinition, RoughSurfaceElement, Sprite, SpriteBuild, SpriteFrameDatastore, SpriteFrameDatastoreContext };
651
+ export { Mutation, PrimaryButton, Query, ResizeHandle, RoughClientDestroyError, RoughClientDestroyedError, RoughCreateModal, RoughEditButton, RoughFeature, RoughInvalidClientError, RoughReplicacheIdentityConflictError, RoughSurfaceContractConflictError, SecondaryButton, SpriteBuildMenu, SpriteFrame, Subscription, createRoughClient, defineRoughSurface, getRoughFeatures, openRoughCreate, whenRoughClientReady };
652
+ export type { FetchUserTokenFn, GetRoughFeaturesOptions, JsonValue, OpenRoughCreateOptions, RoughCleanup, RoughClient, RoughClientOptions, RoughCreateModalElement, RoughEditButtonElement, RoughEditModalElement, RoughFeatureElement, RoughFeatureSubscription, RoughModalHandle, RoughSurfaceDefinition, Sprite, SpriteBuild, SpriteFrameDatastore, SpriteFrameDatastoreContext };