pinstripe 0.31.1 → 0.33.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.
Files changed (62) hide show
  1. package/cli.js +23 -33
  2. package/lib/background_job.js +42 -0
  3. package/lib/background_jobs/_file_importer.js +1 -0
  4. package/lib/{commands → background_jobs}/purge_used_hashes.js +1 -3
  5. package/lib/command.js +40 -15
  6. package/lib/command.test.js +32 -0
  7. package/lib/commands/generate_app.js +5 -3
  8. package/lib/commands/generate_background_job.js +47 -0
  9. package/lib/commands/generate_command.js +2 -2
  10. package/lib/commands/generate_component.js +2 -3
  11. package/lib/commands/generate_migration.js +13 -13
  12. package/lib/commands/generate_model.js +6 -9
  13. package/lib/commands/generate_project.js +14 -9
  14. package/lib/commands/generate_service.js +2 -2
  15. package/lib/commands/generate_static_site.js +1 -3
  16. package/lib/commands/generate_view.js +2 -2
  17. package/lib/commands/list_background_jobs.js +15 -0
  18. package/lib/commands/list_commands.js +6 -0
  19. package/lib/commands/list_views.js +1 -3
  20. package/lib/commands/run_background_job.js +11 -0
  21. package/lib/commands/start_server.js +4 -7
  22. package/lib/component.js +7 -4
  23. package/lib/components/helpers.js +18 -6
  24. package/lib/components/pinstripe_document.js +6 -2
  25. package/lib/components/pinstripe_frame.js +3 -3
  26. package/lib/components/pinstripe_modal.js +26 -7
  27. package/lib/database/client.js +65 -0
  28. package/lib/database/constants.js +13 -1
  29. package/lib/database/row.js +18 -23
  30. package/lib/database/table.js +107 -107
  31. package/lib/database.js +10 -2
  32. package/lib/defer.js +10 -10
  33. package/lib/defer.test.js +11 -0
  34. package/lib/extensions/multi-tenant/database/row.js +22 -0
  35. package/lib/extensions/multi-tenant/models/_file_importer.js +1 -0
  36. package/lib/extensions/multi-tenant/models/tenant.js +14 -0
  37. package/lib/extensions/multi-tenant/services/database.js +4 -1
  38. package/lib/extensions/multi-tenant/services/run_background_job.js +27 -0
  39. package/lib/index.js +1 -0
  40. package/lib/inflector.js +4 -0
  41. package/lib/markdown.js +13 -5
  42. package/lib/project.js +0 -2
  43. package/lib/registry.js +3 -3
  44. package/lib/services/bot.js +9 -9
  45. package/lib/services/cli_utils.js +19 -71
  46. package/lib/services/render_form.js +10 -5
  47. package/lib/services/render_table.js +48 -0
  48. package/lib/services/run_background_job.js +8 -0
  49. package/lib/services/server.js +1 -1
  50. package/lib/views/docs/docs/guides/introduction.md +1 -1
  51. package/lib/views/shared/_button.js +52 -11
  52. package/lib/views/shared/_danger_area.js +78 -0
  53. package/lib/views/shared/_editable_area.js +4 -4
  54. package/lib/views/shared/_form.js +53 -8
  55. package/lib/views/shared/_pagination.js +47 -0
  56. package/lib/views/shared/_panel.js +4 -0
  57. package/lib/views/shared/_section.js +4 -0
  58. package/lib/views/shared/_shell/index.js +2 -1
  59. package/lib/views/shared/_table.js +139 -0
  60. package/package.json +10 -10
  61. package/development.db +0 -0
  62. package/lib/services/args.js +0 -9
package/cli.js CHANGED
@@ -1,46 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { spawn } from 'child_process';
4
-
5
3
  import { Project } from './lib/project.js';
6
4
  import { Command } from './lib/command.js';
7
5
  import { importAll } from './lib/import_all.js';
8
6
  import { Workspace } from './lib/workspace.js';
9
7
 
10
8
  (async () => {
11
- const { entryPath, localPinstripePath, exists } = await Project.instance;
12
- const { argv, env, execPath } = process;
13
- const args = argv.slice(2);
9
+ const { entryPath, exists } = await Project.instance;
10
+ const { argv } = process;
11
+ const [name, ...args ] = argv.slice(2);
14
12
 
15
- if (env.IS_LOCAL_PINSTRIPE != 'true' && localPinstripePath) {
16
- spawn(execPath, [localPinstripePath, ...args], {
17
- env: { ...env, IS_LOCAL_PINSTRIPE: 'true' },
18
- stdio: 'inherit'
19
- });
20
- } else {
21
- if(entryPath){
22
- import(entryPath);
23
- }
13
+ if(entryPath){
14
+ import(entryPath);
15
+ }
24
16
 
25
- await importAll();
17
+ await importAll();
26
18
 
27
- if(exists){
28
- Command.unregister('generate-project');
29
- } else {
30
- const allowedCommands = ['generate-project', 'list-commands'];
31
- Command.names.forEach(commandName => {
32
- if(!allowedCommands.includes(commandName)){
33
- Command.unregister(commandName);
34
- }
35
- });
36
- }
37
-
38
- try {
39
- await Workspace.run(async function(){
40
- await this.runCommand(...args);
41
- });
42
- } catch(e) {
43
- console.error(e);
44
- }
19
+ if(exists){
20
+ Command.names.forEach(commandName => {
21
+ if(!Command.for(commandName).internal) Command.unregister(commandName);
22
+ });
23
+ } else {
24
+ Command.names.forEach(commandName => {
25
+ if(!Command.for(commandName).external) Command.unregister(commandName);
26
+ });
27
+ }
28
+
29
+ try {
30
+ await Workspace.run(async function(){
31
+ await this.runCommand(name, args);
32
+ });
33
+ } catch(e) {
34
+ console.error(e);
45
35
  }
46
36
  })();
@@ -0,0 +1,42 @@
1
+
2
+ import { Class } from './class.js';
3
+ import { inflector } from './inflector.js';
4
+ import { Registry } from './registry.js';
5
+ import { ServiceConsumer } from './service_consumer.js';
6
+
7
+ export const BackgroundJob = Class.extend().include({
8
+ meta(){
9
+ this.assignProps({ name: 'BackgroundJob' });
10
+
11
+ this.include(Registry);
12
+ this.include(ServiceConsumer);
13
+
14
+ this.assignProps({
15
+ normalizeName(name){
16
+ return inflector.dasherize(name);
17
+ },
18
+
19
+ get schedules(){
20
+ if(!this.hasOwnProperty('_schedules')){
21
+ this._schedules = [];
22
+ }
23
+ return this._schedules;
24
+ },
25
+
26
+ schedule(...args){
27
+ this.schedules.push(args);
28
+ return this;
29
+ },
30
+
31
+ async run(context, name){
32
+ await context.fork().run(async context => {
33
+ await this.create(name, context).run();
34
+ });
35
+ },
36
+ });
37
+ },
38
+
39
+ run(){
40
+ console.error(`No such background job "${this.constructor.name}" exists.`);
41
+ }
42
+ });
@@ -0,0 +1 @@
1
+ export { BackgroundJob as default } from 'pinstripe';
@@ -4,10 +4,8 @@ export default {
4
4
  this.schedule('*/5 * * * *');
5
5
  },
6
6
 
7
- minutesUntilExpiry: 30,
8
-
9
7
  async run(){
10
- await this.database.withoutTenantScope.usedHashes.where({
8
+ await this.database.usedHashes.where({
11
9
  expiresAtLt: new Date()
12
10
  }).delete();
13
11
  }
package/lib/command.js CHANGED
@@ -4,9 +4,15 @@ import { inflector } from './inflector.js';
4
4
  import { Registry } from './registry.js';
5
5
  import { ServiceConsumer } from './service_consumer.js';
6
6
 
7
+ const optionPattern = /^-([a-z]|-[a-z\-]+)$/;
8
+
7
9
  export const Command = Class.extend().include({
8
10
  meta(){
9
- this.assignProps({ name: 'Command' });
11
+ this.assignProps({
12
+ name: 'Command',
13
+ internal: true,
14
+ external: false
15
+ });
10
16
 
11
17
  this.include(Registry);
12
18
  this.include(ServiceConsumer);
@@ -16,24 +22,43 @@ export const Command = Class.extend().include({
16
22
  return inflector.dasherize(name);
17
23
  },
18
24
 
19
- get schedules(){
20
- if(!this.hasOwnProperty('_schedules')){
21
- this._schedules = [];
22
- }
23
- return this._schedules;
24
- },
25
-
26
- schedule(...args){
27
- this.schedules.push(args);
28
- return this;
29
- },
30
-
31
- async run(context, name = 'list-commands', ...args){
25
+ async run(context, name = 'list-commands', params = {}){
32
26
  await context.fork().run(async context => {
33
- context.args = [ ...args ];
27
+ context.params = Array.isArray(params) ? this.extractParams(params) : params;
34
28
  await this.create(name, context).run();
35
29
  });
36
30
  },
31
+
32
+ extractParams(_args = []){
33
+ const args = [ ..._args ];
34
+ const out = {};
35
+ let currentName;
36
+ while(args.length){
37
+ const arg = args.shift();
38
+ const matches = arg.match(optionPattern);
39
+ if(matches){
40
+ currentName = inflector.camelize(matches[1]);
41
+ if(out[currentName] === undefined){
42
+ out[currentName] = [];
43
+ }
44
+ } else {
45
+ if(currentName === undefined){
46
+ currentName = 'args';
47
+ out[currentName] = [];
48
+ }
49
+ out[currentName].push(arg);
50
+ }
51
+ }
52
+ Object.keys(out).forEach(name => {
53
+ const value = out[name];
54
+ if(!value.length){
55
+ out[name] = true;
56
+ } else {
57
+ out[name] = value.join(' ');
58
+ }
59
+ });
60
+ return out;
61
+ }
37
62
  });
38
63
  },
39
64
 
@@ -0,0 +1,32 @@
1
+ import { Command } from "./command.js";
2
+
3
+ [
4
+ { args: [], expectedParams: {} },
5
+ { args: ["-a"], expectedParams: { a: true } },
6
+ { args: ["--apple"], expectedParams: { apple: true } },
7
+ { args: ["--apple", "--pear"], expectedParams: { apple: true, pear: true } },
8
+ { args: ["Hello world!"], expectedParams: { args: "Hello world!" } },
9
+ { args: ["Hello", "world!"], expectedParams: { args: "Hello world!" } },
10
+ {
11
+ args: [
12
+ "Hello", "world!",
13
+ "--apple",
14
+ "--pear",
15
+ "--plum-color", "purple",
16
+ "--other-fruit", "peach", "orange",
17
+ ],
18
+ expectedParams: {
19
+ args: "Hello world!",
20
+ apple: true,
21
+ pear: true,
22
+ plumColor: "purple",
23
+ otherFruit: "peach orange",
24
+ },
25
+ },
26
+ ].forEach(({ args, expectedParams }, i) => {
27
+ test(`Command.extractParams (${i}})`, () => {
28
+ expect(Command.extractParams(args)).toStrictEqual(expectedParams);
29
+ });
30
+ });
31
+
32
+
@@ -2,10 +2,10 @@
2
2
 
3
3
  export default {
4
4
  async run(){
5
- const [ name = '' ] = this.args;
5
+ const { name = '' } = this.params;
6
6
  const normalizedName = this.inflector.snakeify(name);
7
7
  if(normalizedName == ''){
8
- console.error('An app name must be given.');
8
+ console.error('An app --name must be given.');
9
9
  process.exit();
10
10
  }
11
11
 
@@ -35,7 +35,9 @@ export default {
35
35
 
36
36
  });
37
37
 
38
- await this.runCommand('generate-view', `${normalizedName}/index`);
38
+ await this.runCommand('generate-view', {
39
+ name: `${normalizedName}/index`
40
+ });
39
41
  }
40
42
  }
41
43
 
@@ -0,0 +1,47 @@
1
+
2
+
3
+ export default {
4
+ async run(){
5
+ const { name = '' } = this.params;
6
+ const normalizedName = this.inflector.snakeify(name);
7
+ if(normalizedName == ''){
8
+ console.error('A background job --name must be given.');
9
+ process.exit();
10
+ }
11
+
12
+ const { inProjectRootDir, generateFile, line, indent } = this.fsBuilder;
13
+
14
+ await inProjectRootDir(async () => {
15
+
16
+ await generateFile(`lib/background_jobs/_file_importer.js`, { skipIfExists: true }, () => {
17
+ line();
18
+ line(`export { BackgroundJob as default } from 'pinstripe';`);
19
+ line();
20
+ });
21
+
22
+ await generateFile(`lib/background_jobs/${normalizedName}.js`, () => {
23
+ line();
24
+ line(`export default {`);
25
+ indent(() => {
26
+ line('meta(){');
27
+ indent(() => {
28
+ line(`this.schedule('* * * * *'); // run every minute`);
29
+ });
30
+ line('}');
31
+ });
32
+ line();
33
+ indent(() => {
34
+ line('run(){');
35
+ indent(() => {
36
+ line(`console.log('${this.inflector.dasherize(normalizedName)} background job coming soon!')`);
37
+ });
38
+ line('}');
39
+ });
40
+ line('};');
41
+ line();
42
+ });
43
+
44
+ });
45
+ }
46
+ }
47
+
@@ -2,10 +2,10 @@
2
2
 
3
3
  export default {
4
4
  async run(){
5
- const [ name = '' ] = this.args;
5
+ const { name = '' } = this.params;
6
6
  const normalizedName = this.inflector.snakeify(name);
7
7
  if(normalizedName == ''){
8
- console.error('A command name must be given.');
8
+ console.error('A command --name must be given.');
9
9
  process.exit();
10
10
  }
11
11
 
@@ -1,10 +1,9 @@
1
1
 
2
2
  export default {
3
3
  async run(){
4
- const { extractArg } = this.cliUtils;
5
- const name = this.inflector.snakeify(extractArg(''));
4
+ const name = this.inflector.snakeify(this.params.name || '');
6
5
  if(name == ''){
7
- console.error('A component name must be given.');
6
+ console.error('A component --name must be given.');
8
7
  process.exit();
9
8
  }
10
9
 
@@ -1,18 +1,18 @@
1
1
 
2
2
  export default {
3
3
  async run(){
4
- const { extractArg, extractFields, extractOptions } = this.cliUtils;
5
4
 
6
- const suffix = this.inflector.snakeify(extractArg('migration'));
7
- const fields = extractFields();
8
- const { table } = extractOptions({
9
- table: (() => {
10
- const matches = suffix.match(/_to_(.+)$/);
11
- if(matches){
12
- return matches[1];
13
- }
14
- })()
15
- });
5
+ const suffix = this.inflector.snakeify(this.params.suffix || 'migration');
6
+
7
+ const { fields = '' } = this.params;
8
+ const normalizedFields = this.cliUtils.normalizeFields(fields);
9
+
10
+ const table = this.params.table || (() => {
11
+ const matches = suffix.match(/_to_(.+)$/);
12
+ if(matches){
13
+ return matches[1];
14
+ }
15
+ })();
16
16
 
17
17
  const unixTime = Math.floor(new Date().getTime() / 1000);
18
18
  const name = `${unixTime}_${suffix}`;
@@ -33,10 +33,10 @@ export default {
33
33
  indent(() => {
34
34
  line(`async migrate(){`);
35
35
  indent(() => {
36
- if(table && fields.length){
36
+ if(table && normalizedFields.length){
37
37
  line(`await this.database.table('${table}', async ${table} => {`);
38
38
  indent(() => {
39
- fields.forEach(({ name, type }) => {
39
+ normalizedFields.forEach(({ name, type }) => {
40
40
  line(`await ${table}.addColumn('${name}', '${type}');`);
41
41
  });
42
42
  })
@@ -2,20 +2,17 @@
2
2
  export default {
3
3
  async run(){
4
4
 
5
- const { extractArg, extractFields } = this.cliUtils;
6
- const name = this.inflector.snakeify(extractArg(''));
5
+ const name = this.inflector.snakeify(this.params.name || '');
7
6
  if(name == ''){
8
- console.error('A model name must be given.');
7
+ console.error('A model --name must be given.');
9
8
  process.exit();
10
9
  }
11
- const fields = extractFields();
12
-
10
+
11
+ let { fields = '' } = this.params;
12
+
13
13
  const collectionName = this.inflector.camelize(this.inflector.pluralize(name));
14
14
  if(!await this.database[collectionName]){
15
- const denormalizedFields = fields.map(({ mandatory, name, type }) => {
16
- return `${ mandatory ? '^' : '' }${name}:${type}`
17
- });
18
- await this.runCommand('generate-migration', `create_${name}`, ...denormalizedFields, '--table', collectionName)
15
+ await this.runCommand('generate-migration', { name: `create_${name}`, fields, table: collectionName});
19
16
  }
20
17
 
21
18
  const { inProjectRootDir, generateFile, line, indent } = this.fsBuilder;
@@ -7,18 +7,23 @@ const defaultDependencies = [
7
7
  ];
8
8
 
9
9
  export default {
10
- async run(){
10
+ meta(){
11
+ this.assignProps({
12
+ external: true,
13
+ internal: false
14
+ });
15
+ },
11
16
 
12
- const { extractArg, extractOptions } = this.cliUtils;
13
- const name = extractArg('');
17
+ async run(){
18
+ const name = this.params.name || '';
14
19
  if(name == ''){
15
- console.error('A project name must be given.');
20
+ console.error('A project --name must be given.');
16
21
  process.exit();
17
22
  }
18
- const { with: dependencies, core } = extractOptions({
19
- with: [],
20
- core: false
21
- });
23
+
24
+ let { with: dependencies = '', core = false } = this.params;
25
+
26
+ dependencies = dependencies.split(/\s+/).map(dependency => dependency.trim());
22
27
 
23
28
  if(!core) defaultDependencies.forEach(dependency => {
24
29
  if(!dependencies.includes(dependency)) dependencies.unshift(dependency);
@@ -134,7 +139,7 @@ export default {
134
139
  line();
135
140
  });
136
141
 
137
- spawnSync('yarn', [ 'add', ...dependencies ], {
142
+ spawnSync('npm', [ 'install', ...dependencies ], {
138
143
  stdio: 'inherit'
139
144
  });
140
145
  });
@@ -1,9 +1,9 @@
1
1
 
2
2
  export default {
3
3
  async run(){
4
- const [ name = '' ] = this.args;
4
+ const { name = '' } = this.params;
5
5
  if(name == ''){
6
- console.error('A service name must be given.');
6
+ console.error('A service --name must be given.');
7
7
  process.exit();
8
8
  }
9
9
 
@@ -6,9 +6,7 @@ import { App, View } from 'pinstripe';
6
6
  export default {
7
7
  async run(){
8
8
 
9
- const { extractOptions } = this.cliUtils;
10
-
11
- const { app = 'main' } = extractOptions();
9
+ const { app = 'main' } = this.params;
12
10
 
13
11
  const { viewNames } = View.mapperFor(App.create(app, this.context).compose());
14
12
 
@@ -4,10 +4,10 @@ import { readFile } from 'fs/promises';
4
4
 
5
5
  export default {
6
6
  async run(){
7
- const [ name = '' ] = this.args;
7
+ const { name = '' } = this.params;
8
8
  let normalizedName = name.replace(/^\//, '');
9
9
  if(name == ''){
10
- console.error('A view name must be given.');
10
+ console.error('A view --name must be given.');
11
11
  process.exit();
12
12
  }
13
13
 
@@ -0,0 +1,15 @@
1
+
2
+ import chalk from 'chalk';
3
+ import { BackgroundJob } from 'pinstripe';
4
+
5
+ export default {
6
+ run(){
7
+ console.log('');
8
+ console.log('The following background jobs are available:');
9
+ console.log('');
10
+ BackgroundJob.names.forEach(backgroundJobName => {
11
+ console.log(` * ${chalk.green(backgroundJobName)}`);
12
+ });
13
+ console.log('');
14
+ }
15
+ };
@@ -3,6 +3,12 @@ import chalk from 'chalk';
3
3
  import { Command } from 'pinstripe';
4
4
 
5
5
  export default {
6
+ meta(){
7
+ this.assignProps({
8
+ external: true,
9
+ });
10
+ },
11
+
6
12
  run(){
7
13
  console.log('');
8
14
  console.log('The following commands are available:');
@@ -4,9 +4,7 @@ import { App, View } from 'pinstripe';
4
4
 
5
5
  export default {
6
6
  run(){
7
- const { extractOptions } = this.cliUtils;
8
-
9
- const { app = 'main' } = extractOptions();
7
+ const { app = 'main' } = this.params;
10
8
 
11
9
  const { viewNames } = View.mapperFor(App.create(app, this.context).compose());
12
10
  console.log('');
@@ -0,0 +1,11 @@
1
+
2
+ export default {
3
+ async run(){
4
+ const { name = '' } = this.params;
5
+ if(name == ''){
6
+ console.error('A background job --name must be given.');
7
+ process.exit();
8
+ }
9
+ this.runBackgroundJob(name);
10
+ }
11
+ };
@@ -1,13 +1,10 @@
1
1
 
2
2
  export default {
3
3
  run(){
4
- const { extractOptions } = this.cliUtils;
5
-
6
- const { app, withoutBot } = extractOptions({
7
- app: `main:${process.env.HOST || '127.0.0.1'}:${parseInt(process.env.PORT || '3000')}`,
8
- withoutBot: false
9
- });
10
-
4
+ const {
5
+ app = `main:${process.env.HOST || '127.0.0.1'}:${parseInt(process.env.PORT || '3000')}`,
6
+ withoutBot = false
7
+ } = this.params;
11
8
 
12
9
  const apps = [];
13
10
  let currentPort = 3000;
package/lib/component.js CHANGED
@@ -203,7 +203,7 @@ export const Component = Class.extend().include({
203
203
  },
204
204
 
205
205
  get isInput(){
206
- return this.is('input, textarea');
206
+ return this.is('input, textarea, select');
207
207
  },
208
208
 
209
209
  get name(){
@@ -220,6 +220,9 @@ export const Component = Class.extend().include({
220
220
  if(this.is('input[type="checkbox"]')){
221
221
  return this.is(':checked') ? true : false;
222
222
  }
223
+ if(this.is('select')){
224
+ return this.findAll('option').map(option => option.value)[this.node.selectedIndex];
225
+ }
223
226
  return this.node.value;
224
227
  },
225
228
 
@@ -597,14 +600,14 @@ function patchAttributes(attributes){
597
600
  if(attributes[key] === undefined){
598
601
  Element.prototype.removeAttribute.call(this.node, key); // work around for https://github.com/cypress-io/cypress/issues/26206
599
602
  // this.node.removeAttribute(key);
603
+ if(key == 'checked') this.node.checked = false;
600
604
  }
601
605
  })
602
606
  Object.keys(attributes).forEach((key) => {
603
607
  if(!currentAttributes.hasOwnProperty(key) || currentAttributes[key] != attributes[key]){
604
608
  this.node.setAttribute(key, attributes[key]);
605
- if(key == 'value'){
606
- this.node.value = attributes[key];
607
- }
609
+ if(key == 'value') this.node.value = attributes[key];
610
+ if(key == 'checked') this.node.checked = true;
608
611
  }
609
612
  })
610
613
  }
@@ -51,11 +51,23 @@ export function normalizeUrl(url, referenceUrl = window.location){
51
51
  const matches = `${url}`.match(/^&(.*)$/);
52
52
  const out = matches ? new URL(referenceUrl) : new URL(url, referenceUrl);
53
53
  if(matches){
54
- if(out.search){
55
- out.search = `${out.search}&${matches[1]}`;
56
- } else {
57
- out.search = `?${matches[1]}`;
58
- }
54
+ out.search = `?${stringifyUrlSearch({
55
+ ...parseUrlSearch(out.search),
56
+ ...parseUrlSearch(`${matches[1]}`)
57
+ })}`;
59
58
  }
60
59
  return out;
61
- }
60
+ }
61
+
62
+ function parseUrlSearch(search){
63
+ const out = {};
64
+ search.replace(/^\?/, '').split('&').forEach(pair => {
65
+ const [key, value] = pair.split('=');
66
+ out[decodeURIComponent(key)] = decodeURIComponent(value);
67
+ });
68
+ return out;
69
+ }
70
+
71
+ function stringifyUrlSearch(search){
72
+ return Object.keys(search).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(search[key])}`).join('&');
73
+ }
@@ -47,6 +47,10 @@ export default {
47
47
  return this.body.progressBar;
48
48
  },
49
49
 
50
+ get loadCacheNamespace(){
51
+ return this.head.find('meta[name="pinstripe-load-cache-namespace"]')?.params.content ?? 'default';
52
+ },
53
+
50
54
  async load(url = this.url.toString(), options = {}){
51
55
  const { replace, method = 'GET' } = options;
52
56
  const previousUrl = this.url.toString();
@@ -65,12 +69,12 @@ export default {
65
69
  },
66
70
 
67
71
  async preload(url){
68
- if(loadCache.get(url.toString())) return;
72
+ if(loadCache.get(`${this.document.loadCacheNamespace}:${url}`)) return;
69
73
  if(preloading[url.toString()]) return;
70
74
  preloading[url.toString()] = true;
71
75
  const response = await fetch(url);
72
76
  const html = await response.text();
73
- loadCache.put(url.toString(), html);
77
+ loadCache.put(`${this.document.loadCacheNamespace}:${url}`, html);
74
78
  delete preloading[url.toString()];
75
79
  }
76
80
  };