Skip to content

Commit

Permalink
Merge pull request #586 from smapiot/develop
Browse files Browse the repository at this point in the history
Release 0.15.8
  • Loading branch information
FlorianRappl authored Mar 8, 2023
2 parents 79157be + 2e9e94f commit 98aee2a
Show file tree
Hide file tree
Showing 102 changed files with 967 additions and 117 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Piral Changelog

## 0.15.8 (tbd)

- Fixed value of `schemaVersion` in *pilet.json* being ignored (#585)
- Added new plugin `piral-tracker` for always-on components
- Added option to reference assets on different URLs in `pilet debug` (#583)
- Added option to merge existing feed pilet metadata in `pilet debug`
- Added DOM events to reflect the loading mechanism in `piral-blazor`
- Added priority loading in `piral-blazor` for special DLLs

## 0.15.7 (February 10, 2023)

- Fixed inconsistency with `pilet build` using explicit target while `pilet publish` using `main` from *package.json*
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 - 2022 smapiot
Copyright (c) 2019 - 2023 smapiot

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
63 changes: 63 additions & 0 deletions docs/concepts/T05-kras-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
title: Kras Configuration
description: The possibilities of configuring the kras proxy server.
section: Tooling
---

# Kras Configuration

The CLI uses [kras](https://www.npmjs.com/package/kras) to resolve a `.krasrc` configuration file.

In this file you can place any configuration you'd like to extend the standard capabilities of the kras proxy server, which is used as a central proxy between the development server and any other servers (real or mocked).

## Piral Injector

The `piral` injector can be used to configure how the application code is loaded. This makes it possible to introduce, e.g., custom headers (such as [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)) into the response - testing the app shell with different settings.

```json
{
"piral": {
"headers": {
"Content-Security-Policy": "default-src 'self'"
}
}
}
```

## Pilet Injector

The `pilet` injector can be used to define the URL to be used when retrieving the pilet assets and metadata. By default, this URL is fully determined by the caller, which is in most cases what you want.

```json
{
"injectors": {
"pilet": {
"assetUrl": "http://custom-domain.com/pilet"
}
}
}
```

You can also define if the config entries from remote pilets (i.e., obtained from a given feed) should be merged. This way, local pilets would still be preferred to remote ones, however, the config values (if any) would be copied over.

```json
{
"injectors": {
"pilet": {
"mergeConfig": true
}
}
}
```

Addtionally, the `pilet` injector can also define `headers` like the `piral` injector.

```json
{
"pilet": {
"headers": {
"Content-Security-Policy": "default-src 'self'"
}
}
}
```
2 changes: 1 addition & 1 deletion docs/deploy/cloudflare.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ To get started, you will need:
- **Framework preset**: `None`
- **Build command:** `npm run build`
- **Build output directory:** `dist/release`
- **Environment variables (advanced)**: By default, Cloudflare Pages uses Node.js 12.18.0, but the Piral CLI [requires a higher version](/en/install/auto/#prerequisites).
- **Environment variables (advanced)**: By default, Cloudflare Pages uses Node.js 12.18.0, but the Piral CLI requires a higher version (at least 14).

Add an environment variable with a **Variable name** of `NODE_VERSION` and a **Value** of `v14.19.2` or higher to tell Cloudflare to use a compatible Node version. Alternatively, add a `.nvmrc` file to your project to specify a Node version.

Expand Down
2 changes: 1 addition & 1 deletion docs/deploy/vercel.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ You can deploy to Vercel through the website UI or using Vercel's CLI (command l
2. Vercel will ask you a few questions to configure the right settings. For most questions you can just press "Enter" and take the default.
3. When asked for the directory where the code is located (`In which directory is your code located? ./`), choose `./dist/release`.
4. When asked `Want to modify these settings? [y/N]`, choose `N`.
5. Your application is deployed! (e.g., [piral-shell.vercel.app](https://piral-shell.vercel.app/))
5. Your application is deployed! (e.g., `piral-shell.vercel.app`)

### Project config with vercel.json

Expand Down
26 changes: 26 additions & 0 deletions docs/reference/C11-loading-strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,29 @@ interface LoadPiletsOptions {
Most importantly, the options have the `fetchPilets` function to get the pilet metadata. The options also transport the `createApi` function to construct an API object dedicated to being used in a pilet.

All the other options are only overrides for specific functionality, e.g., to determine how exactly a pilet is loaded the `loadPilet` option can be used.

## Example: Wait for an Event

Let's say you want to use the standard strategy, but with one addition: Instead of finishing when the pilets are loaded, you want to wait until some event is thrown. This could be very helpful, e.g., when you deal with Blazor and actually want to wait until Blazor is fully ready to render components.

```ts
import { standardStrategy } from 'piral-base';

const instance = createInstance({
async: (options, pilets) => {
standardStrategy(options, pilets);
return new Promise(resolve => {
window.addEventListener('loaded-blazor-pilet', (ev: CustomEvent) => {
if (ev.detail.name === '@mycompany/blazor-layout') {
resolve();
}
});
});
},
plugins: [...createStandardApi(), createBlazorApi({ lazy: false })],
};
```
The code above uses the standard strategy but does return a different promise, which only resolves when the `loaded-blazor-pilet` event for a particular (and important) pilet using Blazor is emitted.
**Important**: In the special case above we require `lazy: false` in the `createBlazorApi` options to trigger the loading of Blazor. Otherwise, we reach a stalemate, where the application is waiting for Blazor to load, while Blazor is waiting for the application to start rendering. By setting `lazy` to false we resolve the stalemate - telling Blazor to proceed with the loading even though the application is not yet rendering.
1 change: 1 addition & 0 deletions docs/static/schemas/pilet-v0.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"properties": {
"schemaVersion": {
"type": "string",
"enum": ["none", "v0", "v1", "v2"],
"description": "The default output schema to be used when building the pilet."
},
"piralInstances": {
Expand Down
2 changes: 1 addition & 1 deletion src/converters/piral-aurelia/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 - 2022 smapiot
Copyright (c) 2019 - 2023 smapiot

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion src/converters/piral-blazor/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 - 2022 smapiot
Copyright (c) 2019 - 2023 smapiot

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
32 changes: 32 additions & 0 deletions src/converters/piral-blazor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,40 @@ Ultimately, you can also call the `SetLanguage` in Piral.Blazor.Core from JavaSc
window.DotNet.invokeMethodAsync('Piral.Blazor.Core', 'SetLanguage', language);
```

Furthermore, it is possible to configure the (initial) log level via the `logLevel` option:

```ts
const instance = createInstance({
// important part
plugins: [createBlazorApi({
logLevel: 1, // everything except trace
})],
// ...
});
```

The levels range from 0 (incl. trace) to 6 (nothing will be logged).

:::

## Events

The `piral-blazor` integration emits some events at the global object (`window`):

- `loading-blazor-core` when the loading of (core) Blazor resources starts
- `loaded-blazor-core` when the loading of (core) Blazor resources ends
- `loading-blazor-pilet` when the loading of a Blazor pilet / its resources starts (`detail` contains the pilet's metadata)
- `loaded-blazor-pilet` when the loading of a Blazor pilet / its resources ends (`detail` contains the pilet's metadata)

You can receive these events using, e.g.:

```js
window.addEventListener('loaded-blazor-pilet', (ev) => {
// your code here - could use:
// ev.detail.name --> name of the pilet
});
```

## License

Piral is released using the MIT license. For more information see the [license file](./LICENSE).
30 changes: 25 additions & 5 deletions src/converters/piral-blazor/src/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ import {
createElement,
destroyElement,
updateElement,
setLogLevel,
} from './interop';
import { BlazorDependencyLoader, BlazorOptions, BlazorRootConfig, WebAssemblyStartOptions } from './types';
import {
BlazorDependencyLoader,
BlazorLogLevel,
BlazorOptions,
BlazorRootConfig,
WebAssemblyStartOptions,
} from './types';
import bootConfig from '../infra.codegen';

const noop = () => {};
Expand Down Expand Up @@ -62,22 +69,34 @@ export interface LanguageOptions {
onChange(inform: (language: string) => void): void;
}

export function createConverter(lazy: boolean, opts?: WebAssemblyStartOptions, language?: LanguageOptions) {
export function createConverter(
lazy: boolean,
opts?: WebAssemblyStartOptions,
language?: LanguageOptions,
logLevel?: BlazorLogLevel,
) {
const bootLoader = createBootLoader(bootConfig.url, bootConfig.satellites);
const boot = (opts?: WebAssemblyStartOptions) =>
bootLoader(opts).then((res) => {
bootLoader(opts).then(async (res) => {
const [_, capabilities] = res;

if (capabilities.includes('logging')) {
if (typeof logLevel === 'number') {
await setLogLevel(logLevel);
}
}

if (language && capabilities.includes('language')) {
if (typeof language.current === 'string') {
setLanguage(language.current);
await setLanguage(language.current);
}

if (typeof language.onChange === 'function') {
language.onChange(setLanguage);
}
}

window.dispatchEvent(new CustomEvent('loaded-blazor-core'));
return res;
});
let loader = !lazy && boot(opts);
Expand Down Expand Up @@ -163,7 +182,7 @@ export function createConverter(lazy: boolean, opts?: WebAssemblyStartOptions, l
});
}

(loader || (loader = boot()))
(loader || (convert.loader = loader = boot()))
.then((config) =>
dependency(config).then(() => {
if (locals.state === 'fresh') {
Expand Down Expand Up @@ -196,5 +215,6 @@ export function createConverter(lazy: boolean, opts?: WebAssemblyStartOptions, l
});

convert.loader = loader;
convert.lazy = lazy;
return convert;
}
28 changes: 19 additions & 9 deletions src/converters/piral-blazor/src/create.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { EventEmitter, PiralPlugin } from 'piral-core';
import { createConverter } from './converter';
import { createDependencyLoader } from './dependencies';
import type { BlazorOptions, PiletBlazorApi, WebAssemblyStartOptions } from './types';
import type { BlazorLogLevel, BlazorOptions, PiletBlazorApi, WebAssemblyStartOptions } from './types';

/**
* Available configuration options for the Blazor plugin.
Expand All @@ -12,6 +12,11 @@ export interface BlazorConfig {
* @default true
*/
lazy?: boolean;
/**
* Determines the used log level, if any. Otherwise, will use
* the default log level (info).
*/
logLevel?: BlazorLogLevel;
/**
* Determines the initial language to use, if any.
* Otherwise, falls back to Blazor's default language.
Expand Down Expand Up @@ -42,21 +47,26 @@ function createDefaultHandler(context: EventEmitter) {
*/
export function createBlazorApi(config: BlazorConfig = {}): PiralPlugin<PiletBlazorApi> {
return (context) => {
const { lazy, initialLanguage, onLanguageChange = createDefaultHandler(context) } = config;
const convert = createConverter(lazy, config.options, {
current: initialLanguage,
onChange: onLanguageChange || (() => {}),
});
const { lazy = true, initialLanguage, onLanguageChange = createDefaultHandler(context), logLevel } = config;
const convert = createConverter(
lazy,
config.options,
{
current: initialLanguage,
onChange: onLanguageChange || (() => {}),
},
logLevel,
);
context.converters.blazor = ({ moduleName, args, dependency, options }) =>
convert(moduleName, dependency, args, options);

return (_, meta) => {
const loader = createDependencyLoader(convert, lazy);
const loader = createDependencyLoader(convert);
let options: BlazorOptions;

return {
defineBlazorReferences(references, satellites) {
return loader.defineBlazorReferences(references, meta, satellites);
defineBlazorReferences(references, satellites, prio) {
return loader.defineBlazorReferences(references, meta, satellites, prio);
},
defineBlazorOptions(blazorOptions: BlazorOptions) {
options = blazorOptions;
Expand Down
37 changes: 34 additions & 3 deletions src/converters/piral-blazor/src/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import type { createConverter } from './converter';
import type { BlazorDependencyLoader, BlazorRootConfig } from './types';

const loadedDependencies = (window.$blazorDependencies ??= []);
const depsWithPrios = (window.$blazorDependencyPrios ??= []);

export function createDependencyLoader(convert: ReturnType<typeof createConverter>, lazy = true) {
export function createDependencyLoader(convert: ReturnType<typeof createConverter>) {
const definedBlazorReferences: Array<string> = [];
const loadedBlazorPilets: Array<string> = [];
let dependency: BlazorDependencyLoader;
Expand All @@ -14,8 +15,23 @@ export function createDependencyLoader(convert: ReturnType<typeof createConverte
getDependency() {
return dependency;
},
defineBlazorReferences(references: Array<string>, meta: Partial<PiletMetadata> = {}, satellites = {}) {
defineBlazorReferences(references: Array<string>, meta: Partial<PiletMetadata> = {}, satellites = {}, prio = 0) {
prio = Math.max(prio, 0);

const depWithPrio = {
prio,
load() {
return Promise.resolve();
},
};

let result: false | Promise<void> = false;
const load = async ([_, capabilities]: BlazorRootConfig) => {
// let others finish first
await Promise.all(depsWithPrios.filter((m) => m.prio > prio).map((m) => m.load()));

window.dispatchEvent(new CustomEvent('loading-blazor-pilet', { detail: meta }));

if (capabilities.includes('load')) {
// new loading mechanism

Expand Down Expand Up @@ -74,9 +90,24 @@ export function createDependencyLoader(convert: ReturnType<typeof createConverte
}
}
}

// inform remaining that this one finished
window.dispatchEvent(new CustomEvent('loaded-blazor-pilet', { detail: meta }));
};
let result = !lazy && convert.loader.then(load);

depWithPrio.load = () => {
if (!result) {
result = convert.loader.then(load);
}

return result;
};
result = !convert.lazy && convert.loader.then(load);
dependency = (config) => result || (result = load(config));

if (prio) {
depsWithPrios.push(depWithPrio);
}
},
async releaseBlazorReferences() {
const references = definedBlazorReferences.splice(0, definedBlazorReferences.length);
Expand Down
Loading

0 comments on commit 98aee2a

Please sign in to comment.