Przeglądaj źródła

* Refactor web to web & worker separate parts

Michaël Van Canneyt 3 lat temu
rodzic
commit
e67986f9f3

+ 1 - 1
demo/opentok/demoopentok.lpr

@@ -3,7 +3,7 @@ program demoopentok;
 {$mode objfpc}
 
 uses
-  JS, Classes, SysUtils, Web, libopentok, browserapp;
+  JS, Classes, SysUtils, Web, weborworker, libopentok, browserapp;
 
 Type
 

+ 64 - 9
packages/fcl-base/serviceworkerapp.pas

@@ -9,7 +9,7 @@ unit ServiceWorkerApp;
 interface
 
 uses
-  SysUtils, Types, JS, web, Classes, CustApp;
+  Classes, SysUtils, Types, JS, weborworker, webworker, CustApp;
 
 type
 
@@ -47,6 +47,56 @@ type
 
 implementation
 
+var
+  EnvNames: TJSObject;
+
+procedure ReloadEnvironmentStrings;
+
+var
+  I : Integer;
+  S,N : String;
+  A,P : TStringDynArray;
+begin
+  if Assigned(EnvNames) then
+    FreeAndNil(EnvNames);
+  EnvNames:=TJSObject.new;
+  S:=self_.Location.search;
+  S:=Copy(S,2,Length(S)-1);
+  A:=TJSString(S).split('&');
+  for I:=0 to Length(A)-1 do
+    begin
+    P:=TJSString(A[i]).split('=');
+    N:=LowerCase(decodeURIComponent(P[0]));
+    if Length(P)=2 then
+      EnvNames[N]:=decodeURIComponent(P[1])
+    else if Length(P)=1 then
+      EnvNames[N]:=''
+    end;
+end;
+
+function MyGetEnvironmentVariable(Const EnvVar: String): String;
+
+Var
+  aName : String;
+
+begin
+  aName:=Lowercase(EnvVar);
+  if EnvNames.hasOwnProperty(aName) then
+    Result:=String(EnvNames[aName])
+  else
+    Result:='';
+end;
+
+function MyGetEnvironmentVariableCount: Integer;
+begin
+  Result:=length(TJSOBject.getOwnPropertyNames(envNames));
+end;
+
+function MyGetEnvironmentString(Index: Integer): String;
+begin
+  Result:=String(EnvNames[TJSOBject.getOwnPropertyNames(envNames)[Index]]);
+end;
+
 { TServiceWorkerApplication }
 
 procedure TServiceWorkerApplication.SetFallbackURL(const AValue: string);
@@ -60,7 +110,7 @@ procedure TServiceWorkerApplication.PutInCache(Request: TJSRequest;
 var
   Cache: TJSCache;
 begin
-  Cache := await(TJSCache,Caches.open(CacheName));
+  Cache := await(TJSCache,self_.Caches.open(CacheName));
   await(TJSCache,Cache.put(Request, Response));
 end;
 
@@ -72,7 +122,7 @@ begin
   Result:=nil;
 
   // First try to get the resource from the cache
-  ResponseFromCache := await(TJSResponse,caches.match(Request));
+  ResponseFromCache := await(TJSResponse,self_.caches.match(Request));
   if Assigned(ResponseFromCache) then
     exit(ResponseFromCache);
 
@@ -87,14 +137,14 @@ begin
 
   // Next try to get the resource from the network
   try
-    ResponseFromNetwork := await(TJSResponse,window.fetch(Request));
+    ResponseFromNetwork := await(TJSResponse,self_.fetch(Request));
     // response may be used only once
     // we need to save clone to put one copy in cache
     // and serve second one
     PutInCache(Request, ResponseFromNetwork.clone());
     exit(ResponseFromNetwork);
   except
-    FallbackResponse := await(TJSResponse,caches.match(FallbackUrl));
+    FallbackResponse := await(TJSResponse,self_.caches.match(FallbackUrl));
     if Assigned(FallbackResponse) then
       exit(FallbackResponse);
 
@@ -119,7 +169,7 @@ end;
 
 procedure TServiceWorkerApplication.DeleteCache(key: string);
 begin
-  await(boolean,caches.delete(key));
+  await(boolean,Self_.caches.delete(key));
 end;
 
 function TServiceWorkerApplication.DeleteOldCaches: jsvalue;
@@ -128,7 +178,7 @@ var
   CachesToDelete, KeyList: TJSArray;
 begin
   CacheKeepList := [CacheName];
-  KeyList := await(TJSArray,caches.keys());
+  KeyList := await(TJSArray,self_.caches.keys());
   CachesToDelete := keyList.filter(
     function (key: JSValue; index: NativeInt; anArray : TJSArray) : Boolean
     begin
@@ -153,7 +203,7 @@ end;
 procedure TServiceWorkerApplication.Install(Event: TJSExtendableEvent);
 begin
   Event.waitUntil(
-    Caches.Open(CacheName)._then(
+    self_.Caches.Open(CacheName)._then(
       TJSPromiseResolver(procedure(Cache: TJSCache)
       begin
         Cache.addAll(Resources);
@@ -204,7 +254,12 @@ begin
 end;
 
 initialization
+  
   IsConsole:=true;
-
+  ReloadEnvironmentStrings;
+  OnGetEnvironmentVariable:=@MyGetEnvironmentVariable;
+  OnGetEnvironmentVariableCount:=@MyGetEnvironmentVariableCount;
+  OnGetEnvironmentString:=@MyGetEnvironmentString;
+  
 end.
 

+ 35 - 520
packages/rtl/web.pas

@@ -18,10 +18,9 @@ unit Web;
 
 interface
 
-uses Types, JS;
+uses Types, JS, weborworker;
 
 Type
-  TJSEvent = Class;
   // Forward definitions
   TJSHTMLElement = Class;
   TJSWindow = class;
@@ -32,10 +31,7 @@ Type
   TJSElement = class;
   TJSCSSStyleSheet = Class;
   TJSNodeFilter = Class;
-  TJSIDBObjectStore = Class;
-  TIDBDatabase = class;
-  TJSIDBRequest = class;
-  TJSEventTarget = class;
+
   TJSMouseEvent = Class;
   TJSWheelEvent = Class;
   TJSKeyBoardEvent = class;
@@ -50,11 +46,11 @@ Type
   TJSFileSystemDirectoryHandleArray = array of TJSFileSystemDirectoryHandle;
   TJSShowOpenFilePickerOptions = class;
   TJSShowSaveFilePickerOptions = class;
-  TJSServiceWorker = class;
   TJSClient = class;
-  TJSRequest = Class;
   TJSResponse = Class;
-  TJSServiceWorkerRegistration = class;
+
+  TJSServiceWorker = weborworker.TJSServiceWorker;
+  TJSServiceWorkerRegistration = weborworker.TJSServiceWorkerRegistration;
 
   { TEventListenerEvent }
 
@@ -71,16 +67,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
   TJSEventHandler = reference to function(Event: TEventListenerEvent): boolean; safecall;
   TJSRawEventHandler = reference to Procedure(Event: TJSEvent); safecall;
 
-  TJSEventTarget = class external name 'EventTarget' (TJSObject)
-  public
-    procedure addEventListener(aname : string; aListener : TJSEventHandler);
-    procedure addEventListener(aname : string; aListener : TJSRawEventHandler);
-    procedure addEventListener(aname : string; aListener : JSValue);
-    function dispatchEvent(event : JSValue) : Boolean;
-    procedure removeEventListener(aname : string; aListener : TJSEventHandler);
-    procedure removeEventListener(aname : string; aListener : TJSRawEventHandler);
-    procedure removeEventListener(aname : string; aListener : JSValue);
-  end;
+  TJSEventTarget = weborworker.TJSEventTarget;
 
   TJSNode = class external name 'Node' (TJSEventTarget)
   Private
@@ -441,52 +428,15 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     property lastElementChild : TJSElement read FlastElementChild;
   end;
 
-  TJSEventInit = record
-    bubbles : boolean;
-    cancelable : boolean;
-    scoped : boolean;
-    composed : boolean;
-  end;
+  TJSEventInit = weborworker.TJSEventInit;
 
-  TJSEvent = class external name 'Event'  (TJSObject)
+  TJSEvent = class external name 'Event' (weborworker.TJSEvent)
   Private
-    FBubbles : Boolean; external name 'bubbles';
-    FCancelable : Boolean; external name 'cancelable';
-    FComposed : Boolean; external name 'composed';
-    FCurrentTarget : TJSEventTarget; external name 'currentTarget';
     FCurrentTargetElement : TJSElement; external name 'currentTarget';
-    FdefaultPrevented : Boolean; external name 'defaultPrevented';
-    FEventPhase : NativeInt; external name 'eventPhase';
-    FTarget : TJSEventTarget; external name 'target';
     FTargetElement : TJSElement; external name 'target';
-    FTimeStamp : NativeInt; external name 'timestamp';
-    FType : String; external name 'type';
-    FIsTrusted : Boolean; external name 'isTrusted';
   Public
-    Const
-      NONE = 0;
-      CAPTURING_PHASE = 1;
-      AT_TARGET  = 2;
-      BUBBLING_PHASE = 3;
-  public    
-    cancelBubble : Boolean;
-    constructor new (aType : String; const aInit : TJSEventInit); overload;
-    constructor new (aType : String); overload;
-    procedure preventDefault;
-    procedure stopImmediatePropagation;
-    procedure stopPropagation;
-    Property bubbles : Boolean Read FBubbles;
-    Property cancelable : Boolean Read FCancelable;
-    Property composed : Boolean Read FComposed;
-    property currentTarget : TJSEventTarget Read FCurrentTarget;
     property currentTargetElement : TJSElement Read FCurrentTargetElement;
-    property defaultPrevented : Boolean Read FdefaultPrevented;
-    property eventPhase : NativeInt Read FEventPhase;
-    property target : TJSEventTarget Read FTarget;
     property targetElement : TJSElement Read FTargetElement;
-    Property timestamp : NativeInt Read FTimeStamp;
-    property _type : string read FType;
-    property isTrusted : Boolean Read FIsTrusted;
   end;
 
 
@@ -1038,30 +988,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     property visibilityState : string read FVisibilityState;
   end;
 
-  TJSConsole = class external name 'Console'  (TJSObject)
-  Public
-    procedure assert(anAssertion : string; Obj1 : JSValue); varargs;
-    Procedure clear;  
-    procedure count; overload;
-    procedure count(aCounter : String);
-    procedure debug(Obj1 : JSValue); varargs of JSValue;
-    procedure error(Obj1 : JSValue); varargs of JSValue;
-    procedure group; overload;
-    procedure group(aLabel : String); overload;
-    procedure groupCollapsed; overload;
-    procedure groupCollapsed(aLabel : String);overload;
-    procedure groupEnd;
-    procedure info(Obj1 : JSValue); varargs of JSValue;
-    procedure log(Obj1 : JSValue); varargs of JSValue;
-    procedure table(args: array of JSValue); overload;
-    procedure table(args: array of JSValue; Columns : Array of string);
-    procedure table(args: TJSObject); overload;
-    procedure table(args: TJSObject; Columns : Array of string); overload;
-    procedure time(aName : string);
-    procedure timeEnd(aName : string);
-    procedure trace;
-    procedure warn(Obj1 : JSValue); varargs of JSValue;
-  end;
+  TJSConsole = weborworker.TJSConsole;
 
 //  TJSBufferSource = class external name 'BufferSource' end;
 //  TJSTypedArray = class external name 'TypedArray' end;
@@ -1383,255 +1310,22 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     property length: NativeInt read FLength;
   end;
 
-  TJSIDBTransactionMode = class
-  const
-    readonly = 'readonly';
-    readwrite = 'readwrite';
-    versionchange = 'versionchange';
-  end;
-
-
-  { TJSIDBTransaction }
-
-  TJSIDBTransaction = class external name 'IDBTransaction'  (TJSEventTarget)
-  private
-    FDB : TIDBDatabase; external name 'db';
-    FError: JSValue; external name 'error';
-    FMode: String; external name 'mode';
-    FObjectStoreNames: TStringDynArray; external name 'objectStoreNames';
-  public
-    procedure abort;
-    function objectStore(aName : String) : TJSIDBObjectStore;
-    property db : TIDBDatabase read FDB;
-    property mode : String read FMode;
-    property objectStoreNames : TStringDynArray read FObjectStoreNames;
-    property error : JSValue read FError;
-  end;
-
-
-  { TJSIDBKeyRange }
-
-  TJSIDBKeyRange = class external name 'IDBKeyRange'  (TJSObject)
-  private
-    FLower: JSValue;
-    FLowerOpen: Boolean;
-    FUpper: JSValue;
-    FUpperOpen: Boolean;
-  Public
-    Class Function bound(aLower,aUpper : JSValue) : TJSIDBKeyRange; overload;
-    Class Function bound(aLower,aUpper : JSValue; aLowerOpen : Boolean) : TJSIDBKeyRange; overload;
-    Class Function bound(aLower,aUpper : JSValue; aLowerOpen,aUpperOpen : Boolean) : TJSIDBKeyRange; overload;
-    Class Function lowerBound(aLower : JSValue) : TJSIDBKeyRange; overload;
-    Class Function lowerBound(aLower : JSValue; aOpen: Boolean) : TJSIDBKeyRange; overload;
-    Class Function only(aValue : JSValue) : TJSIDBKeyRange;
-    Class Function upperBound(aUpper : JSValue) : TJSIDBKeyRange; overload;
-    Class Function upperBound(aUpper : JSValue; aOpen: Boolean) : TJSIDBKeyRange; overload;
-    function includes (aValue : JSValue) : Boolean;
-    property lower : JSValue read FLower;
-    property lowerOpen : Boolean read FLowerOpen;
-    property upper : JSValue read FUpper;
-    property upperOpen : Boolean read FUpperOpen;
-  end;
-
-  TJSIDBIndexParameters = record
-    unique : boolean;
-    multiEntry : boolean;
-    locale : string;
-  end;
-
-
-  { TJSIDBIndex }
-
-  TJSIDBIndex = class external name 'IDBIndex'  (TJSObject)
-  private
-    FKeyPath: JSValue; external name 'keyPath';
-    FMultiEntry: Boolean; external name 'multiEntry';
-    FObjectStore: TJSIDBObjectStore; external name 'objectStore';
-    FUnique: boolean; external name 'unique';
-  public
-    name : string;
-    function count : TJSIDBRequest;
-    function get(aKey : jsValue) : TJSIDBRequest; overload;
-    function get(aKey : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getAll(aKey : jsValue) : TJSIDBRequest; overload;
-    function getAll(aKey : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getAll(aKey : jsValue; ACount : NativeInt) : TJSIDBRequest; overload;
-    function getAll(aKey : TJSIDBKeyRange; ACount : NativeInt) : TJSIDBRequest; overload;
-    function getAllKeys(aKey : jsValue) : TJSIDBRequest; overload;
-    function getAllKeys(aKey : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getAllKeys(aKey : jsValue; ACount : NativeInt) : TJSIDBRequest; overload;
-    function getAllKeys(aKey : TJSIDBKeyRange; ACount : NativeInt) : TJSIDBRequest; overload;
-    function getKey(aKey : jsValue) : TJSIDBRequest;
-    function openCursor : TJSIDBRequest; overload;
-    function openCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function openCursor(aKeyRange : TJSIDBKeyRange; ADirection : String) : TJSIDBRequest;overload;
-    function openKeyCursor : TJSIDBRequest;overload;
-    function openKeyCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest;overload;
-    function openKeyCursor(aKeyRange : TJSIDBKeyRange; ADirection : String) : TJSIDBRequest;overload;
-    Property keyPath : JSValue Read FKeyPath;
-    property multiEntry : Boolean read FMultiEntry;
-    property objectStore : TJSIDBObjectStore read FObjectStore;
-    property unique : boolean read FUnique;
-  end;
-
-  TJSIDBCursorDirection = class external name 'IDBCursorDirection'  (TJSObject)
-  Const
-    next = 'next';
-    nextUnique = 'nextUnique';
-    prev = 'prev';
-    prevUnique = 'prevUnique';
-  end;
-
-
-  { TJSIDBCursor }
-
-  TJSIDBCursor = class external name 'IDBCursor'  (TJSObject)
-  private
-    FDirection: string; external name 'direction';
-    FKey: JSValue; external name 'key';
-    FValue : JSValue; external name 'value';
-    FPrimaryKey: JSValue; external name 'primaryKey';
-    FSource: JSValue; external name 'source';
-    FSourceAsIndex: TJSIDBIndex; external name 'source';
-    FSourceAsStore: TJSIDBObjectStore; external name 'source';
-  Public
-    procedure advance(aCount : NativeInt); overload;
-    procedure advance(aKey : JSValue); overload;
-    procedure continue(aKey : JSValue); overload;
-    procedure continue; overload;
-    procedure continuePrimaryKey(aKey : JSValue); overload;
-    procedure continuePrimaryKey(aKey,aPrimaryKey : JSValue); overload;
-    procedure delete;
-    procedure update(aValue : JSValue);
-    property source : JSValue read FSource;
-    property sourceAsStore : TJSIDBObjectStore read FSourceAsStore;
-    property sourceAsIndex : TJSIDBIndex read FSourceAsIndex;
-    property key : JSValue read FKey;
-    Property Value : JSValue Read FValue;
-    property primaryKey : JSValue read FPrimaryKey;
-    property direction : string read FDirection;
-  end;
-
-  TJSIDBObjectStore = class external name 'IDBObjectStore'  (TJSEventTarget)
-  public
-    function add(aValue : JSValue; aKey : String) : TJSIDBRequest;
-    function add(aValue : JSValue) : TJSIDBRequest;
-    function clear : TJSIDBRequest;
-    function delete(aKey : string) : TJSIDBRequest;
-    function delete(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest;
-    function get(aKey : string) : TJSIDBRequest; overload;
-    function get(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getKey(aKey : string) : TJSIDBRequest; overload;
-    function getKey(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getAll : TJSIDBRequest; overload;
-    function getAll(aKey : String) : TJSIDBRequest; overload;
-    function getAll(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getAll(aKey : String; aCount: NativeInt) : TJSIDBRequest; overload;
-    function getAll(aKeyRange : TJSIDBKeyRange; aCount: NativeInt) : TJSIDBRequest; overload;
-    function getAllKeys(aKey : String) : TJSIDBRequest; overload;
-    function getAllKeys(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function getAllKeys(aKey : String; aCount: NativeInt) : TJSIDBRequest; overload;
-    function getAllKeys(aKeyRange : TJSIDBKeyRange; aCount: NativeInt) : TJSIDBRequest; overload;
-    function createIndex (aIndexName : String; KeyPath : String)  : TJSIDBIndex; overload;
-    function createIndex (aIndexName : String; KeyPath : String; Options : TJSIDBIndexParameters)  : TJSIDBIndex; overload;
-    function createIndex (aIndexName : String; KeyPath : Array of String)  : TJSIDBIndex; overload;
-    function createIndex (aIndexName : String; KeyPath : Array of String; Options : TJSIDBIndexParameters)  : TJSIDBIndex; overload;
-    Procedure deleteIndex (aIndexName : String);
-    function index (aIndexName : String)  : TJSIDBIndex;
-    function put(aValue : JSValue; aKey : String) : TJSIDBRequest; overload;
-    function put(aValue : JSValue) : TJSIDBRequest; overload;
-    function openCursor : TJSIDBRequest; overload;
-    function openCursor(aKey : String) : TJSIDBRequest; overload;
-    function openCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function openCursor(aKey : String; aDirection : string) : TJSIDBRequest; overload;
-    function openCursor(aKeyRange : TJSIDBKeyRange; aDirection : string) : TJSIDBRequest; overload;
-    function openKeyCursor : TJSIDBRequest; overload;
-    function openKeyCursor(aKey : String) : TJSIDBRequest; overload;
-    function openKeyCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    function openKeyCursor(aKey : String; aDirection : string) : TJSIDBRequest; overload;
-    function openKeyCursor(aKeyRange : TJSIDBKeyRange; aDirection : string) : TJSIDBRequest; overload;
-    function count : TJSIDBRequest; overload;
-    function count(aKey : String) : TJSIDBRequest; overload;
-    function count(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
-    property Indexes [aIndexName : String] : TJSIDBIndex read index;
-  end;
-
-  { TJSIDBRequest }
-
-  TJSIDBRequest = class external name 'IDBRequest'  (TJSEventTarget)
-  private
-    Ferror : JSValue; external name 'error'; // standards are not quite clear on this one
-    FReadyState: string; external name 'readyState';
-    FResult: JSValue; external name 'result';
-    FResultDatabase: TIDBDatabase; external name 'result';
-    FResultIndex: TJSIDBIndex; external name 'result';
-    FResultObjectStore : TJSIDBObjectStore; external name 'result';
-    FResultCursor : TJSIDBCursor; external name 'result';
-    FSourceDatabase: TIDBDatabase; external name 'source';
-    FSourceIndex: TJSIDBIndex; external name 'source';
-    FSourceObjectStore : TJSIDBObjectStore; external name 'source';
-    FSourceCursor : TJSIDBCursor; external name 'source';
-    FSource: JSValue; external name 'source';
-    FTransaction: TJSIDBTransaction; external name 'transaction';
-  Public
-    onerror : TJSEventHandler;
-    onsuccess : TJSEventHandler;
-    Property error : JSValue read FError;
-    property readyState : string read FReadyState;
-
-    property result : JSValue read FResult;
-    property resultAsObjectStore : TJSIDBObjectStore read FResultObjectStore;
-    property resultAsCursor : TJSIDBCursor read FResultCursor;
-    property resultAsIndex : TJSIDBIndex read FResultIndex;
-    property resultAsDatabase : TIDBDatabase read FResultDatabase;
-
-    property source : JSValue read FSource;
-    property sourceAsObjectStore : TJSIDBObjectStore read FSourceObjectStore;
-    property sourceAsCursor : TJSIDBCursor read FSourceCursor;
-    property sourceAsIndex : TJSIDBIndex read FSourceIndex;
-    property sourceAsDatabase : TIDBDatabase read FSourceDatabase;
-
-    property transaction : TJSIDBTransaction read FTransaction;
-  end;
-
-  TJSIDBOpenDBRequest = class external name 'IDBOpenDBRequest' (TJSIDBRequest)
-  Public
-    onblocked : TJSEventHandler;
-    onupgradeneeded : TJSEventHandler;
-  end;
-
-  TJSCreateObjectStoreOptions = record
-    keyPath : jsValue;
-    autoIncrement : boolean;
-  end;
+  { IndexedDB - moved to weborworker}
 
-  { TIDBDatabase }
+  TJSIDBTransactionMode = weborworker.TJSIDBTransactionMode;
+  TJSIDBTransaction = weborworker.TJSIDBTransaction;
+  TJSIDBKeyRange = weborworker.TJSIDBKeyRange;
+  TJSIDBIndexParameters = weborworker.TJSIDBIndexParameters;
+  TJSIDBIndex = weborworker.TJSIDBIndex;
+  TJSIDBCursorDirection = weborworker.TJSIDBCursorDirection;
+  TJSIDBCursor = weborworker.TJSIDBCursor;
+  TJSIDBObjectStore = weborworker.TJSIDBObjectStore;
+  TJSIDBRequest = weborworker.TJSIDBRequest;
+  TJSIDBOpenDBRequest = weborworker.TJSIDBOpenDBRequest;
+  TJSCreateObjectStoreOptions = weborworker.TJSCreateObjectStoreOptions;
+  TIDBDatabase = weborworker.TIDBDatabase;
+  TJSIDBFactory = weborworker.TJSIDBFactory;
 
-  TIDBDatabase = class external name 'IDBDatabase' (TJSEventTarget)
-  private
-    FName: string; external name 'name';
-    FobjectStoreNames: TStringDynArray; external name 'objectStoreNames';
-    FVersion: integer; external name 'version';
-  public
-    procedure close;
-    function createObjectStore(aName : string) : TJSIDBObjectStore; overload;
-    function createObjectStore(aName : string; Options: TJSCreateObjectStoreOptions) : TJSIDBObjectStore; overload;
-    procedure deleteObjectStore(aName : string);
-    function transaction(aStoreNames : array of string) : TJSIDBTransaction; overload;
-    function transaction(aStoreNames : array of string; aMode : string) : TJSIDBTransaction; overload;
-    property name : string read FName;
-    property version : integer read FVersion;
-    property objectStoreNames : TStringDynArray read FobjectStoreNames;
-  end;
-
-  TJSIDBFactory = class external name 'IDBFactory' (TJSEventTarget)
-  public
-    function open(aName : string) : TJSIDBOpenDBRequest;
-    function open(aName : string; aVersion : Integer) : TJSIDBOpenDBRequest;
-    function deleteDatabase(aName : string) : TJSIDBOpenDBRequest;
-    function cmp (a,b : jsValue) : NativeInt;
-  end;
-  
   { TJSStorage }
 
   TJSStorage = class external name 'Storage' (TJSEventTarget)
@@ -1710,12 +1404,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
   TJSMediaDevices = class external name 'MediaDevices' (TJSEventTarget)
   end;
 
-  TJSWorker = class external name 'Worker' (TJSEventTarget)
-  public
-    constructor new(aURL : string);
-    procedure postMessage(aValue : JSValue);
-    procedure postMessage(aValue : JSValue; aList : TJSValueDynArray);
-  end;
+  TJSWorker = weborworker.TJSWorker;
 
   TJSMessagePort = class external name 'MessagePort' (TJSEventTarget)
   Public
@@ -1737,9 +1426,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     property port : TJSMessagePort Read FPort;
   end;
 
-  TJSExtendableEvent = class external name 'ExtendableEvent' (TJSEvent)
-    Procedure waitUntil(aPromise : TJSPromise);
-  end;
+  TJSExtendableEvent = weborworker.TJSExtendableEvent;
 
   { TJSExtendableMessageEvent }
 
@@ -1765,24 +1452,6 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     Property SourceClient : TJSClient Read FSourceClient;
   end;
 
-  { TJSFetchEvent }
-
-  TJSFetchEvent = class external name 'FetchEvent' (TJSExtendableEvent)
-  private
-    FClientID: String; external name 'clientId';
-    FReplacesClientID: String; external name 'replacesClientId';
-    FRequest: TJSRequest; external name 'request';
-    FResultingClientID: String; external name 'resultingClientId';
-    FPreloadResponse: TJSPromise; external name 'preloadResponse';
-  Public
-    Procedure respondWith(aPromise : TJSPromise);
-    Procedure respondWith(aResponse : TJSResponse);
-    Property ClientId : String Read FClientID;
-    Property PreloadResponse : TJSPromise Read FPreloadResponse;
-    Property ReplacesClientID : String Read FReplacesClientID;
-    Property ResultingClientID : String Read FResultingClientID;
-    Property request : TJSRequest Read FRequest;
-  end;
 
   { TJSClient }
 
@@ -1801,55 +1470,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     Property URL : String Read FURL;
   end;
 
-  { TJSServiceWorker }
 
-  TJSServiceWorker = class external name 'ServiceWorker' (TJSWorker)
-  private
-    FRegistration: TJSServiceWorkerRegistration; external name 'registration';
-    FScriptURL: String;  external name 'scriptURL';
-    FState: string;  external name 'state';
-  Public
-    property State : string read FState;
-    property ScriptURL : String Read FscriptURL;
-    property Registration: TJSServiceWorkerRegistration read FRegistration;
-  end;
-
-  { TJSNavigationPreloadState }
-
-  TJSNavigationPreloadState = class external name 'navigationPreloadState'
-  public
-    enabled: boolean;
-    headerValue: string;
-  end;
-
-  { TJSNavigationPreload }
-
-  TJSNavigationPreload = class external name 'navigationPreload' (TJSObject)
-  public
-    function enable: boolean; async;
-    function disable: boolean; async;
-    function setHeaderValue(Value: string): TJSPromise;
-    function getState: TJSNavigationPreloadState; async;
-  end;
-
-  { TJSServiceWorkerRegistration }
-
-  TJSServiceWorkerRegistration = class external name 'ServiceWorkerRegistration'  (TJSObject)
-  private
-    FActive: TJSServiceWorker; external name 'active';
-    FInstalling: TJSServiceWorker; external name 'installing';
-    FScope: string; external name 'scope';
-    FWaiting: TJSServiceWorker; external name 'waiting';
-    FNavigationPreload: TJSNavigationPreload; external name 'navigationPreload';
-  public
-    function unregister : TJSPromise;
-    procedure update;
-    property Active : TJSServiceWorker read FActive;
-    property Scope : string read FScope;
-    property Waiting : TJSServiceWorker read FWaiting;
-    property Installing : TJSServiceWorker read FInstalling;
-    property NavigationPreload: TJSNavigationPreload read FNavigationPreload;
-  end;
 
   TJSServiceWorkerContainerOptions = record
     scope : string;
@@ -1906,6 +1527,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     FOnline: boolean; external name 'onLine';
     FPlatform: string; external name 'platform';
     FServiceWorker: TJSServiceWorkerContainer; external name 'serviceWorker';
+    FStorage: TJSStorageManager; external name 'storage';
     FUserAgent: string; external name 'userAgent';
     fClipBoard : TJSClipBoard; external name 'clipboard';
     FPermissions: TJSPermissions; external name 'permissions';
@@ -1933,6 +1555,7 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     property serviceWorker : TJSServiceWorkerContainer read FServiceWorker;
     property ClipBoard : TJSClipBoard Read FCLipboard;
     property permissions: TJSPermissions read FPermissions;
+    property storage : TJSStorageManager Read FStorage;
   end;
 
   { TJSTouchEvent }
@@ -1992,51 +1615,13 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
   end;
 
 
-  TJSParamEnumCallBack = reference to procedure (const aKey,aValue : string);
-  TJSURLSearchParams = class external name 'URLSearchParams' (TJSObject)
-  Public
-    constructor new(aQuery : String);
-    Procedure append(const aName,aValue : string);
-    Procedure delete(const aName : string);
-    Function entries : TJSIterator;
-    Procedure foreach(aEnumCallBack : TJSParamEnumCallBack);
-    function get(const aName : string) : JSValue;
-    // If you're sure the value exists...
-    function getString(const aName : string) : string; external name 'get';
-    function getAll(const aName : string) : TStringDynArray;
-    function has(const aName : string) : Boolean;
-    Function keys : TJSIterator; reintroduce;
-    Procedure set_(const aName,aValue : string); external name 'set';
-    Procedure sort;
-    Function values : TJSIterator; reintroduce;
-  end;
-
-  TJSURL = class external name 'URL' (TJSObject)
-  Private
-    FOrigin : String; external name 'origin';
-    FSearchParams : TJSURLSearchParams; external name 'searchParams';
-  public
-    hash : string;
-    host : string;
-    hostname : string;
-    href : string;
-    password : string;
-    pathname : string;
-    port : string;
-    protocol : string;
-    search : string;
-    username : string;
-    constructor new(aURL : String);
-    constructor new(aURL,aBase : String);
-    class function createObjectURL(const v: JSValue): string;
-    class function revokeObjectURL(const S : String): string;
-    function toJSON : String;
-    Property Origin : String Read FOrigin;
-    property SearchParams : TJSURLSearchParams read FSearchParams;
-  end;
-  TJSURLDynArray = array of TJSURL;
 
-  TJSTimerCallBack = reference to procedure; safecall;
+  TJSURLSearchParams = weborworker.TJSURLSearchParams;
+  TJSURL = weborworker.TJSURL;
+  TJSURLDynArray = weborworker.TJSURLDynArray;
+
+
+  TJSTimerCallBack = weborworker.TJSTimerCallBack;
   Theader = Array [0..1] of String;
   THeaderArray = Array of Theader;
 
@@ -2156,78 +1741,8 @@ TEventListenerEvent = class external name 'EventListener_Event' (TJSObject)
     property didTimeout: Boolean read FDidTimeout;
   end;
 
-  TJSCacheDeleteOptions = class external name 'Object' (TJSObject)
-    ignoreSearch : Boolean;
-    ignoreMethod : Boolean;
-    ignoreVary : Boolean;
-    cacheName : string;
-  end;
-
-  { TJSRequest }
-
-  TJSRequest = class external name 'Request' (TJSObject)
-  private
-    FBody: TJSReadableStream; external name 'body';
-    FBodyUsed: Boolean; external name 'bodyUsed';
-    FCache: String; external name 'cache';
-    FCredentials: TJSObject; external name 'credentials';
-    FDestination: String; external name 'destination';
-    FHeaders: TJSObject; external name 'headers';
-    FIntegrity: String; external name 'integrity';
-    FMethod: String; external name 'method';
-    FMode: String; external name 'mode';
-    FReferrer: string; external name 'referrer';
-    FReferrerPolicy: string; external name 'referrerPolicy';
-    FURL: String;external name 'url';
-  Public
-    Property body : TJSReadableStream Read FBody;
-    property bodyUsed : Boolean Read FBodyUsed;
-    Property Cache : String Read FCache;
-    Property Credentials : TJSObject Read FCredentials;
-    Property Destination : String Read FDestination;
-    // TODO : actually Headers object
-    Property Headers : TJSObject Read FHeaders;
-    Property Integrity : String Read FIntegrity;
-    Property Method : String Read FMethod;
-    Property Mode : String Read FMode;
-    Property Referrer : string Read FReferrer;
-    Property ReferrerPolicy : string Read FReferrerPolicy;
-    Property URL : String Read FURL;
-  end;
-  TJSRequestDynArray = array of TJSRequest;
-
-  TJSCache = class external name 'Cache' (TJSObject)
-  Public
-    Function add(aRequest : String) : TJSPromise;
-    Function add(aRequest : TJSURL) : TJSPromise;
-    Function addAll(aRequests : TJSStringDynArray) : TJSPromise;
-    Function addAll(aRequests : TJSURLDynArray) : TJSPromise;
-    Function addAll(aRequests : TJSValueDynArray) : TJSPromise;
-    Function put(aRequest : String; aResponse : TJSResponse) : TJSPromise;
-    Function put(aRequest : TJSRequest; aResponse : TJSResponse) : TJSPromise;
-    Function delete(aRequest : String) : TJSPromise;
-    Function delete(aRequest : TJSRequest) : TJSPromise;
-    Function delete(aRequest : String; aOptions : TJSObject) : TJSPromise;
-    Function delete(aRequest : TJSRequest; aOptions : TJSObject) : TJSPromise;
-    Function delete(aRequest : String; aOptions : TJSCacheDeleteOptions) : TJSPromise;
-    Function delete(aRequest : TJSRequest; aOptions : TJSCacheDeleteOptions) : TJSPromise;
-    Function keys : TJSPromise; reintroduce;
-    Function match(aRequest : String): TJSPromise;
-    Function match(aRequest : TJSRequest): TJSPromise;
-    Function matchAll(aRequest : TJSStringDynArray): TJSPromise;
-    Function matchAll(aRequest : TJSRequestDynArray): TJSPromise;
-    Function matchAll(aRequests : TJSValueDynArray) : TJSPromise;
-  end;
-
-  TJSCacheStorage = class external name 'CacheStorage' (TJSObject)
-  Public
-    function delete(aName : string) : TJSPromise; // resolves to boolean
-    function has(aName : string) : TJSPromise;
-    Function keys : TJSPromise; reintroduce;
-    Function match(aRequest : String): TJSPromise;
-    Function match(aRequest : TJSRequest): TJSPromise;
-    function open(aName : string) : TJSPromise;
-  end;
+  TJSCache = weborworker.TJSCache;
+  TJSCacheStorage = weborworker.TJSCacheStorage;
 
   TJSWindowArray = Array of TJSWindow;
   TIdleCallbackProc = reference to procedure(idleDeadline: TJSIdleDeadline);

+ 706 - 0
packages/rtl/weborworker.pas

@@ -0,0 +1,706 @@
+unit weborworker;
+
+{$mode objfpc}
+{$modeswitch externalclass}
+
+interface
+
+uses
+  JS, types;
+
+type
+  TJSEventTarget = class;
+  TIDBDatabase = class;
+  TJSIDBObjectStore = class;
+  TJSIDBRequest = class;
+  TJSServiceWorker = class;
+
+  TJSStorageManager = class external name 'StorageManager' (TJSObject)
+    function estimate : TJSPromise;
+    function persist : TJSPromise;
+    function persisted : TJSPromise;
+  end;
+
+
+  TJSConsole = class external name 'Console'  (TJSObject)
+  Public
+    procedure assert(anAssertion : string; Obj1 : JSValue); varargs;
+    Procedure clear;
+    procedure count; overload;
+    procedure count(aCounter : String);
+    procedure debug(Obj1 : JSValue); varargs of JSValue;
+    procedure error(Obj1 : JSValue); varargs of JSValue;
+    procedure group; overload;
+    procedure group(aLabel : String); overload;
+    procedure groupCollapsed; overload;
+    procedure groupCollapsed(aLabel : String);overload;
+    procedure groupEnd;
+    procedure info(Obj1 : JSValue); varargs of JSValue;
+    procedure log(Obj1 : JSValue); varargs of JSValue;
+    procedure table(args: array of JSValue); overload;
+    procedure table(args: array of JSValue; Columns : Array of string);
+    procedure table(args: TJSObject); overload;
+    procedure table(args: TJSObject; Columns : Array of string); overload;
+    procedure time(aName : string);
+    procedure timeEnd(aName : string);
+    procedure trace;
+    procedure warn(Obj1 : JSValue); varargs of JSValue;
+  end;
+
+  TJSTimerCallBack = reference to procedure; safecall;
+
+  TJSEventInit = record
+    bubbles : boolean;
+    cancelable : boolean;
+    scoped : boolean;
+    composed : boolean;
+  end;
+
+  TJSEvent = class external name 'Event'  (TJSObject)
+  Private
+    FBubbles : Boolean; external name 'bubbles';
+    FCancelable : Boolean; external name 'cancelable';
+    FComposed : Boolean; external name 'composed';
+    FCurrentTarget : TJSEventTarget; external name 'currentTarget';
+    FdefaultPrevented : Boolean; external name 'defaultPrevented';
+    FEventPhase : NativeInt; external name 'eventPhase';
+    FTarget : TJSEventTarget; external name 'target';
+    FTimeStamp : NativeInt; external name 'timestamp';
+    FType : String; external name 'type';
+    FIsTrusted : Boolean; external name 'isTrusted';
+  Public
+    Const
+      NONE = 0;
+      CAPTURING_PHASE = 1;
+      AT_TARGET  = 2;
+      BUBBLING_PHASE = 3;
+  public
+    cancelBubble : Boolean;
+    constructor new (aType : String; const aInit : TJSEventInit); overload;
+    constructor new (aType : String); overload;
+    procedure preventDefault;
+    procedure stopImmediatePropagation;
+    procedure stopPropagation;
+    Property bubbles : Boolean Read FBubbles;
+    Property cancelable : Boolean Read FCancelable;
+    Property composed : Boolean Read FComposed;
+    property currentTarget : TJSEventTarget Read FCurrentTarget;
+//    property currentTargetElement : TJSElement Read FCurrentTargetElement;
+    property defaultPrevented : Boolean Read FdefaultPrevented;
+    property eventPhase : NativeInt Read FEventPhase;
+    property target : TJSEventTarget Read FTarget;
+//    property targetElement : TJSElement Read FTargetElement;
+    Property timestamp : NativeInt Read FTimeStamp;
+    property _type : string read FType;
+    property isTrusted : Boolean Read FIsTrusted;
+  end;
+
+  TJSExtendableEvent = class external name 'ExtendableEvent' (TJSEvent)
+    Procedure waitUntil(aPromise : TJSPromise);
+  end;
+
+  TJSEventHandler = reference to function(Event: TJSEvent): boolean; safecall;
+  TJSRawEventHandler = reference to Procedure(Event: TJSEvent); safecall;
+
+  TJSEventTarget = class external name 'EventTarget' (TJSObject)
+  public
+    procedure addEventListener(aname : string; aListener : TJSEventHandler);
+    procedure addEventListener(aname : string; aListener : TJSRawEventHandler);
+    procedure addEventListener(aname : string; aListener : JSValue);
+    function dispatchEvent(event : JSValue) : Boolean;
+    procedure removeEventListener(aname : string; aListener : TJSEventHandler);
+    procedure removeEventListener(aname : string; aListener : TJSRawEventHandler);
+    procedure removeEventListener(aname : string; aListener : JSValue);
+  end;
+
+
+  TJSStructuredSerializeOptions = class external name 'Object' (TJSObject)
+    transfer : TJSValueDynArray;
+  end;
+
+  TJSReadableStream = class external name 'ReadableStream' (TJSObject)
+  private
+    flocked: Boolean; external name 'locked';
+  public
+    property locked: Boolean read flocked;
+    constructor new(underlyingSource: TJSObject);
+    constructor new(underlyingSource, queueingStrategy: TJSObject);
+    function cancel(reason: String): TJSPromise;
+    function getReader(): TJSObject; overload;
+    function getReader(mode: TJSObject): TJSObject; overload;
+    function pipeThrough(transformStream: TJSObject): TJSReadableStream; overload;
+    function pipeThrough(transformStream, options: TJSObject): TJSReadableStream; overload;
+    function pipeTo(destination: TJSObject): TJSPromise; overload;
+    function pipeTo(destination, options: TJSObject): TJSPromise; overload;
+    function tee(): TJSArray; // array containing two TJSReadableStream instances
+  end;
+
+  TJSBlob = class external name 'Blob' (TJSEventTarget)
+  private
+    FSize: NativeInt; external name 'size';
+    FType: string; external name  'type';
+  Public
+    procedure close;
+    function slice : TJSBlob; overload;
+    function slice(aStart : NativeInt) : TJSBlob; overload;
+    function slice(aStart,aEnd : NativeInt) : TJSBlob; overload;
+    function slice(aStart,aEnd : NativeInt; AContentType : String) : TJSBlob; overload;
+    function arrayBuffer : TJSPromise;
+    property size : NativeInt read FSize;
+    property _type : string read FType; deprecated;
+    property type_ : string read FType;
+  end;
+
+  TJSBody = class external name 'Body' (TJSObject)
+  private
+    fbody: TJSReadableStream; external name 'body';
+    fbodyUsed: Boolean; external name 'bodyUsed';
+  public
+    property body: TJSReadableStream read fbody;
+    property bodyUsed: Boolean read fbodyUsed;
+    function arrayBuffer(): TJSPromise; // resolves to TJSArrayBuffer
+    //function blob(): TJSPromise; // resolves to TJSBlob
+    function blob: TJSBlob; {$IFNDEF SkipAsync}async;{$ENDIF}
+    function json(): TJSPromise; // resolves to JSON / TJSValue
+    //function text(): TJSPromise; // resolves to USVString, always decoded using UTF-8
+    function text(): string; {$IFNDEF SkipAsync}async;{$ENDIF}
+  end;
+
+
+  TJSResponse = class external name 'Response' (TJSBody)
+  private
+    fheaders: TJSObject;external name 'headers';
+    fok: Boolean; external name 'ok';
+    fredirected: Boolean; external name 'redirected';
+    fstatus: NativeInt; external name 'status';
+    fstatusText: String; external name 'statusText';
+    ftype: String; external name 'type';
+    furl: String; external name 'url';
+    fuseFinalUrl: Boolean; external name 'useFinalUrl';
+  public
+    property headers: TJSObject read fheaders; //
+    property ok: Boolean read fok;
+    property redirected: Boolean read fredirected;
+    property status: NativeInt read fstatus;
+    property statusText: String read fstatusText; //
+    property type_: String read ftype; //
+    property url: String read furl; //
+    property useFinalUrl: Boolean read fuseFinalUrl write fuseFinalUrl;
+    constructor new(body: TJSObject; init: TJSObject); overload; varargs; external name 'new';
+    constructor new(Msg: string; init: TJSObject); overload; varargs; external name 'new';
+    function clone(): TJSResponse;
+    function error(): TJSResponse;
+    function redirect(url: String; Status: NativeInt): TJSResponse;
+  end;
+
+
+
+
+  TJSIDBTransactionMode = class
+  const
+    readonly = 'readonly';
+    readwrite = 'readwrite';
+    versionchange = 'versionchange';
+  end;
+
+
+  { TJSIDBTransaction }
+
+  TJSIDBTransaction = class external name 'IDBTransaction'  (TJSEventTarget)
+  private
+    FDB : TIDBDatabase; external name 'db';
+    FError: JSValue; external name 'error';
+    FMode: String; external name 'mode';
+    FObjectStoreNames: TStringDynArray; external name 'objectStoreNames';
+  public
+    procedure abort;
+    function objectStore(aName : String) : TJSIDBObjectStore;
+    property db : TIDBDatabase read FDB;
+    property mode : String read FMode;
+    property objectStoreNames : TStringDynArray read FObjectStoreNames;
+    property error : JSValue read FError;
+  end;
+
+
+  { TJSIDBKeyRange }
+
+  TJSIDBKeyRange = class external name 'IDBKeyRange'  (TJSObject)
+  private
+    FLower: JSValue;
+    FLowerOpen: Boolean;
+    FUpper: JSValue;
+    FUpperOpen: Boolean;
+  Public
+    Class Function bound(aLower,aUpper : JSValue) : TJSIDBKeyRange; overload;
+    Class Function bound(aLower,aUpper : JSValue; aLowerOpen : Boolean) : TJSIDBKeyRange; overload;
+    Class Function bound(aLower,aUpper : JSValue; aLowerOpen,aUpperOpen : Boolean) : TJSIDBKeyRange; overload;
+    Class Function lowerBound(aLower : JSValue) : TJSIDBKeyRange; overload;
+    Class Function lowerBound(aLower : JSValue; aOpen: Boolean) : TJSIDBKeyRange; overload;
+    Class Function only(aValue : JSValue) : TJSIDBKeyRange;
+    Class Function upperBound(aUpper : JSValue) : TJSIDBKeyRange; overload;
+    Class Function upperBound(aUpper : JSValue; aOpen: Boolean) : TJSIDBKeyRange; overload;
+    function includes (aValue : JSValue) : Boolean;
+    property lower : JSValue read FLower;
+    property lowerOpen : Boolean read FLowerOpen;
+    property upper : JSValue read FUpper;
+    property upperOpen : Boolean read FUpperOpen;
+  end;
+
+  TJSIDBIndexParameters = record
+    unique : boolean;
+    multiEntry : boolean;
+    locale : string;
+  end;
+
+
+  { TJSIDBIndex }
+
+  TJSIDBIndex = class external name 'IDBIndex'  (TJSObject)
+  private
+    FKeyPath: JSValue; external name 'keyPath';
+    FMultiEntry: Boolean; external name 'multiEntry';
+    FObjectStore: TJSIDBObjectStore; external name 'objectStore';
+    FUnique: boolean; external name 'unique';
+  public
+    name : string;
+    function count : TJSIDBRequest;
+    function get(aKey : jsValue) : TJSIDBRequest; overload;
+    function get(aKey : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getAll(aKey : jsValue) : TJSIDBRequest; overload;
+    function getAll(aKey : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getAll(aKey : jsValue; ACount : NativeInt) : TJSIDBRequest; overload;
+    function getAll(aKey : TJSIDBKeyRange; ACount : NativeInt) : TJSIDBRequest; overload;
+    function getAllKeys(aKey : jsValue) : TJSIDBRequest; overload;
+    function getAllKeys(aKey : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getAllKeys(aKey : jsValue; ACount : NativeInt) : TJSIDBRequest; overload;
+    function getAllKeys(aKey : TJSIDBKeyRange; ACount : NativeInt) : TJSIDBRequest; overload;
+    function getKey(aKey : jsValue) : TJSIDBRequest;
+    function openCursor : TJSIDBRequest; overload;
+    function openCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function openCursor(aKeyRange : TJSIDBKeyRange; ADirection : String) : TJSIDBRequest;overload;
+    function openKeyCursor : TJSIDBRequest;overload;
+    function openKeyCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest;overload;
+    function openKeyCursor(aKeyRange : TJSIDBKeyRange; ADirection : String) : TJSIDBRequest;overload;
+    Property keyPath : JSValue Read FKeyPath;
+    property multiEntry : Boolean read FMultiEntry;
+    property objectStore : TJSIDBObjectStore read FObjectStore;
+    property unique : boolean read FUnique;
+  end;
+
+  TJSIDBCursorDirection = class external name 'IDBCursorDirection'  (TJSObject)
+  Const
+    next = 'next';
+    nextUnique = 'nextUnique';
+    prev = 'prev';
+    prevUnique = 'prevUnique';
+  end;
+
+
+  { TJSIDBCursor }
+
+  TJSIDBCursor = class external name 'IDBCursor'  (TJSObject)
+  private
+    FDirection: string; external name 'direction';
+    FKey: JSValue; external name 'key';
+    FValue : JSValue; external name 'value';
+    FPrimaryKey: JSValue; external name 'primaryKey';
+    FSource: JSValue; external name 'source';
+    FSourceAsIndex: TJSIDBIndex; external name 'source';
+    FSourceAsStore: TJSIDBObjectStore; external name 'source';
+  Public
+    procedure advance(aCount : NativeInt); overload;
+    procedure advance(aKey : JSValue); overload;
+    procedure continue(aKey : JSValue); overload;
+    procedure continue; overload;
+    procedure continuePrimaryKey(aKey : JSValue); overload;
+    procedure continuePrimaryKey(aKey,aPrimaryKey : JSValue); overload;
+    procedure delete;
+    procedure update(aValue : JSValue);
+    property source : JSValue read FSource;
+    property sourceAsStore : TJSIDBObjectStore read FSourceAsStore;
+    property sourceAsIndex : TJSIDBIndex read FSourceAsIndex;
+    property key : JSValue read FKey;
+    Property Value : JSValue Read FValue;
+    property primaryKey : JSValue read FPrimaryKey;
+    property direction : string read FDirection;
+  end;
+
+  TJSIDBObjectStore = class external name 'IDBObjectStore'  (TJSEventTarget)
+  public
+    function add(aValue : JSValue; aKey : String) : TJSIDBRequest;
+    function add(aValue : JSValue) : TJSIDBRequest;
+    function clear : TJSIDBRequest;
+    function delete(aKey : string) : TJSIDBRequest;
+    function delete(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest;
+    function get(aKey : string) : TJSIDBRequest; overload;
+    function get(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getKey(aKey : string) : TJSIDBRequest; overload;
+    function getKey(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getAll : TJSIDBRequest; overload;
+    function getAll(aKey : String) : TJSIDBRequest; overload;
+    function getAll(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getAll(aKey : String; aCount: NativeInt) : TJSIDBRequest; overload;
+    function getAll(aKeyRange : TJSIDBKeyRange; aCount: NativeInt) : TJSIDBRequest; overload;
+    function getAllKeys(aKey : String) : TJSIDBRequest; overload;
+    function getAllKeys(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function getAllKeys(aKey : String; aCount: NativeInt) : TJSIDBRequest; overload;
+    function getAllKeys(aKeyRange : TJSIDBKeyRange; aCount: NativeInt) : TJSIDBRequest; overload;
+    function createIndex (aIndexName : String; KeyPath : String)  : TJSIDBIndex; overload;
+    function createIndex (aIndexName : String; KeyPath : String; Options : TJSIDBIndexParameters)  : TJSIDBIndex; overload;
+    function createIndex (aIndexName : String; KeyPath : Array of String)  : TJSIDBIndex; overload;
+    function createIndex (aIndexName : String; KeyPath : Array of String; Options : TJSIDBIndexParameters)  : TJSIDBIndex; overload;
+    Procedure deleteIndex (aIndexName : String);
+    function index (aIndexName : String)  : TJSIDBIndex;
+    function put(aValue : JSValue; aKey : String) : TJSIDBRequest; overload;
+    function put(aValue : JSValue) : TJSIDBRequest; overload;
+    function openCursor : TJSIDBRequest; overload;
+    function openCursor(aKey : String) : TJSIDBRequest; overload;
+    function openCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function openCursor(aKey : String; aDirection : string) : TJSIDBRequest; overload;
+    function openCursor(aKeyRange : TJSIDBKeyRange; aDirection : string) : TJSIDBRequest; overload;
+    function openKeyCursor : TJSIDBRequest; overload;
+    function openKeyCursor(aKey : String) : TJSIDBRequest; overload;
+    function openKeyCursor(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    function openKeyCursor(aKey : String; aDirection : string) : TJSIDBRequest; overload;
+    function openKeyCursor(aKeyRange : TJSIDBKeyRange; aDirection : string) : TJSIDBRequest; overload;
+    function count : TJSIDBRequest; overload;
+    function count(aKey : String) : TJSIDBRequest; overload;
+    function count(aKeyRange : TJSIDBKeyRange) : TJSIDBRequest; overload;
+    property Indexes [aIndexName : String] : TJSIDBIndex read index;
+  end;
+
+  { TJSIDBRequest }
+
+  TJSIDBRequest = class external name 'IDBRequest'  (TJSEventTarget)
+  private
+    Ferror : JSValue; external name 'error'; // standards are not quite clear on this one
+    FReadyState: string; external name 'readyState';
+    FResult: JSValue; external name 'result';
+    FResultDatabase: TIDBDatabase; external name 'result';
+    FResultIndex: TJSIDBIndex; external name 'result';
+    FResultObjectStore : TJSIDBObjectStore; external name 'result';
+    FResultCursor : TJSIDBCursor; external name 'result';
+    FSourceDatabase: TIDBDatabase; external name 'source';
+    FSourceIndex: TJSIDBIndex; external name 'source';
+    FSourceObjectStore : TJSIDBObjectStore; external name 'source';
+    FSourceCursor : TJSIDBCursor; external name 'source';
+    FSource: JSValue; external name 'source';
+    FTransaction: TJSIDBTransaction; external name 'transaction';
+  Public
+    onerror : TJSEventHandler;
+    onsuccess : TJSEventHandler;
+    Property error : JSValue read FError;
+    property readyState : string read FReadyState;
+
+    property result : JSValue read FResult;
+    property resultAsObjectStore : TJSIDBObjectStore read FResultObjectStore;
+    property resultAsCursor : TJSIDBCursor read FResultCursor;
+    property resultAsIndex : TJSIDBIndex read FResultIndex;
+    property resultAsDatabase : TIDBDatabase read FResultDatabase;
+
+    property source : JSValue read FSource;
+    property sourceAsObjectStore : TJSIDBObjectStore read FSourceObjectStore;
+    property sourceAsCursor : TJSIDBCursor read FSourceCursor;
+    property sourceAsIndex : TJSIDBIndex read FSourceIndex;
+    property sourceAsDatabase : TIDBDatabase read FSourceDatabase;
+
+    property transaction : TJSIDBTransaction read FTransaction;
+  end;
+
+  TJSIDBOpenDBRequest = class external name 'IDBOpenDBRequest' (TJSIDBRequest)
+  Public
+    onblocked : TJSEventHandler;
+    onupgradeneeded : TJSEventHandler;
+  end;
+
+  TJSCreateObjectStoreOptions = record
+    keyPath : jsValue;
+    autoIncrement : boolean;
+  end;
+
+  { TIDBDatabase }
+
+  TIDBDatabase = class external name 'IDBDatabase' (TJSEventTarget)
+  private
+    FName: string; external name 'name';
+    FobjectStoreNames: TStringDynArray; external name 'objectStoreNames';
+    FVersion: integer; external name 'version';
+  public
+    procedure close;
+    function createObjectStore(aName : string) : TJSIDBObjectStore; overload;
+    function createObjectStore(aName : string; Options: TJSCreateObjectStoreOptions) : TJSIDBObjectStore; overload;
+    procedure deleteObjectStore(aName : string);
+    function transaction(aStoreNames : array of string) : TJSIDBTransaction; overload;
+    function transaction(aStoreNames : array of string; aMode : string) : TJSIDBTransaction; overload;
+    property name : string read FName;
+    property version : integer read FVersion;
+    property objectStoreNames : TStringDynArray read FobjectStoreNames;
+  end;
+
+  TJSIDBFactory = class external name 'IDBFactory' (TJSEventTarget)
+  public
+    function open(aName : string) : TJSIDBOpenDBRequest;
+    function open(aName : string; aVersion : Integer) : TJSIDBOpenDBRequest;
+    function deleteDatabase(aName : string) : TJSIDBOpenDBRequest;
+    function cmp (a,b : jsValue) : NativeInt;
+  end;
+
+  { TJSRequest }
+
+  TJSRequest = class external name 'Request' (TJSObject)
+  private
+    FBody: TJSReadableStream; external name 'body';
+    FBodyUsed: Boolean; external name 'bodyUsed';
+    FCache: String; external name 'cache';
+    FCredentials: TJSObject; external name 'credentials';
+    FDestination: String; external name 'destination';
+    FHeaders: TJSObject; external name 'headers';
+    FIntegrity: String; external name 'integrity';
+    FMethod: String; external name 'method';
+    FMode: String; external name 'mode';
+    FReferrer: string; external name 'referrer';
+    FReferrerPolicy: string; external name 'referrerPolicy';
+    FURL: String;external name 'url';
+  Public
+    Property body : TJSReadableStream Read FBody;
+    property bodyUsed : Boolean Read FBodyUsed;
+    Property Cache : String Read FCache;
+    Property Credentials : TJSObject Read FCredentials;
+    Property Destination : String Read FDestination;
+    // TODO : actually Headers object
+    Property Headers : TJSObject Read FHeaders;
+    Property Integrity : String Read FIntegrity;
+    Property Method : String Read FMethod;
+    Property Mode : String Read FMode;
+    Property Referrer : string Read FReferrer;
+    Property ReferrerPolicy : string Read FReferrerPolicy;
+    Property URL : String Read FURL;
+  end;
+  TJSRequestDynArray = array of TJSRequest;
+
+  TJSCacheDeleteOptions = class external name 'Object' (TJSObject)
+    ignoreSearch : Boolean;
+    ignoreMethod : Boolean;
+    ignoreVary : Boolean;
+    cacheName : string;
+  end;
+
+  TJSParamEnumCallBack = reference to procedure (const aKey,aValue : string);
+
+  TJSURLSearchParams = class external name 'URLSearchParams' (TJSObject)
+  Public
+    constructor new(aQuery : String);
+    Procedure append(const aName,aValue : string);
+    Procedure delete(const aName : string);
+    Function entries : TJSIterator;
+    Procedure foreach(aEnumCallBack : TJSParamEnumCallBack);
+    function get(const aName : string) : JSValue;
+    // If you're sure the value exists...
+    function getString(const aName : string) : string; external name 'get';
+    function getAll(const aName : string) : TStringDynArray;
+    function has(const aName : string) : Boolean;
+    Function keys : TJSIterator; reintroduce;
+    Procedure set_(const aName,aValue : string); external name 'set';
+    Procedure sort;
+    Function values : TJSIterator; reintroduce;
+  end;
+
+  TJSURL = class external name 'URL' (TJSObject)
+  Private
+    FOrigin : String; external name 'origin';
+    FSearchParams : TJSURLSearchParams; external name 'searchParams';
+  public
+    hash : string;
+    host : string;
+    hostname : string;
+    href : string;
+    password : string;
+    pathname : string;
+    port : string;
+    protocol : string;
+    search : string;
+    username : string;
+    constructor new(aURL : String);
+    constructor new(aURL,aBase : String);
+    class function createObjectURL(const v: JSValue): string;
+    class function revokeObjectURL(const S : String): string;
+    function toJSON : String;
+    Property Origin : String Read FOrigin;
+    property SearchParams : TJSURLSearchParams read FSearchParams;
+  end;
+  TJSURLDynArray = array of TJSURL;
+
+
+    { TJSNavigationPreloadState }
+
+    TJSNavigationPreloadState = class external name 'navigationPreloadState'
+    public
+      enabled: boolean;
+      headerValue: string;
+    end;
+
+    { TJSNavigationPreload }
+
+    TJSNavigationPreload = class external name 'navigationPreload' (TJSObject)
+    public
+      function enable: boolean; async;
+      function disable: boolean; async;
+      function setHeaderValue(Value: string): TJSPromise;
+      function getState: TJSNavigationPreloadState; async;
+    end;
+
+
+  TJSWorker = class external name 'Worker' (TJSEventTarget)
+  public
+    constructor new(aURL : string);
+    procedure postMessage(aValue : JSValue);
+    procedure postMessage(aValue : JSValue; aList : TJSValueDynArray);
+  end;
+
+
+
+  { TJSServiceWorkerRegistration }
+
+  TJSServiceWorkerRegistration = class external name 'ServiceWorkerRegistration'  (TJSObject)
+  private
+    FActive: TJSServiceWorker; external name 'active';
+    FInstalling: TJSServiceWorker; external name 'installing';
+    FScope: string; external name 'scope';
+    FWaiting: TJSServiceWorker; external name 'waiting';
+    FNavigationPreload: TJSNavigationPreload; external name 'navigationPreload';
+  public
+    function unregister : TJSPromise;
+    procedure update;
+    property Active : TJSServiceWorker read FActive;
+    property Scope : string read FScope;
+    property Waiting : TJSServiceWorker read FWaiting;
+    property Installing : TJSServiceWorker read FInstalling;
+    property NavigationPreload: TJSNavigationPreload read FNavigationPreload;
+  end;
+
+  { TJSServiceWorker }
+
+  TJSServiceWorker = class external name 'ServiceWorker' (TJSWorker)
+  private
+    FRegistration: TJSServiceWorkerRegistration; external name 'registration';
+    FScriptURL: String;  external name 'scriptURL';
+    FState: string;  external name 'state';
+  Public
+    property State : string read FState;
+    property ScriptURL : String Read FscriptURL;
+    property Registration: TJSServiceWorkerRegistration read FRegistration;
+  end;
+
+
+  { TJSRequest }
+
+  TJSCache = class external name 'Cache' (TJSObject)
+  Public
+    Function add(aRequest : String) : TJSPromise;
+    Function add(aRequest : TJSURL) : TJSPromise;
+    Function addAll(aRequests : TJSStringDynArray) : TJSPromise;
+    Function addAll(aRequests : TJSURLDynArray) : TJSPromise;
+    Function addAll(aRequests : TJSValueDynArray) : TJSPromise;
+    Function put(aRequest : String; aResponse : TJSResponse) : TJSPromise;
+    Function put(aRequest : TJSRequest; aResponse : TJSResponse) : TJSPromise;
+    Function delete(aRequest : String) : TJSPromise;
+    Function delete(aRequest : TJSRequest) : TJSPromise;
+    Function delete(aRequest : String; aOptions : TJSObject) : TJSPromise;
+    Function delete(aRequest : TJSRequest; aOptions : TJSObject) : TJSPromise;
+    Function delete(aRequest : String; aOptions : TJSCacheDeleteOptions) : TJSPromise;
+    Function delete(aRequest : TJSRequest; aOptions : TJSCacheDeleteOptions) : TJSPromise;
+    Function keys : TJSPromise; reintroduce;
+    Function match(aRequest : String): TJSPromise;
+    Function match(aRequest : TJSRequest): TJSPromise;
+    Function matchAll(aRequest : TJSStringDynArray): TJSPromise;
+    Function matchAll(aRequest : TJSRequestDynArray): TJSPromise;
+    Function matchAll(aRequests : TJSValueDynArray) : TJSPromise;
+  end;
+
+  TJSCacheStorage = class external name 'CacheStorage' (TJSObject)
+  Public
+    function delete(aName : string) : TJSPromise; // resolves to boolean
+    function has(aName : string) : TJSPromise;
+    Function keys : TJSPromise; reintroduce;
+    Function match(aRequest : String): TJSPromise;
+    Function match(aRequest : TJSRequest): TJSPromise;
+    function open(aName : string) : TJSPromise;
+  end;
+
+  { TJSFetchEvent }
+
+  TJSFetchEvent = class external name 'FetchEvent' (TJSExtendableEvent)
+  private
+    FClientID: String; external name 'clientId';
+    FReplacesClientID: String; external name 'replacesClientId';
+    FRequest: TJSRequest; external name 'request';
+    FResultingClientID: String; external name 'resultingClientId';
+    FPreloadResponse: TJSPromise; external name 'preloadResponse';
+  Public
+    Procedure respondWith(aPromise : TJSPromise);
+    Procedure respondWith(aResponse : TJSResponse);
+    Property ClientId : String Read FClientID;
+    Property PreloadResponse : TJSPromise Read FPreloadResponse;
+    Property ReplacesClientID : String Read FReplacesClientID;
+    Property ResultingClientID : String Read FResultingClientID;
+    Property request : TJSRequest Read FRequest;
+  end;
+
+
+  TJSMicrotaskProcedure = reference to Procedure;
+
+  TJSImageBitmapOptions = class external name 'Object' (TJSObject)
+    imageOrientation : string;
+    premultiplyAlpha : string;
+    colorSpaceConversion : String;
+    resizeWidth : NativeInt;
+    resizeHeight : NativeInt;
+    resizeQuality : String;
+  end;
+
+
+
+  TWindowOrWorkerGlobalScope = Class external name 'Object' (TJSObject)
+  Private
+    FisSecureContext : boolean; external name 'isSecureContext';
+    FIDBFactory : TJSIDBFactory; external name 'IDBFactory';
+    fcaches : TJSCacheStorage; external name 'caches';
+  Public
+    Function setInterval(ahandler : TJSTimerCallBack; aInterval : NativeUInt) : NativeInt; varargs;
+    Function setTimeout(ahandler : TJSTimerCallBack; aTimeout : NativeUInt) : NativeInt; varargs;
+    Function setTimeout(ahandler : TJSTimerCallBack) : NativeInt;
+    Procedure clearInterval(aID: NativeInt);
+    Procedure clearTimeout(aID: NativeInt);
+    procedure queueMicrotask(callback : TJSMicrotaskProcedure);
+    Function createImageBitmap(Source : JSValue) : TJSPromise;
+    Function createImageBitmap(Source : JSValue; aOptions : TJSImageBitmapOptions) : TJSPromise;
+    Function createImageBitmap(Source : JSValue; sx,sy,sw,sh : NativeInt; aOptions : TJSImageBitmapOptions) : TJSPromise;
+    Function structuredClone(value : JSValue) : JSValue;
+    Function structuredClone(value : JSValue; aOptions : TJSStructuredSerializeOptions) : JSValue;
+    function fetch(resource: String; init: TJSObject): TJSPromise; overload; external name 'fetch';
+    //function fetch(resource: String): TJSPromise; overload; external name 'fetch';
+    function fetch(resource: String): TJSResponse; {$IFNDEF SkipAsync}async;{$ENDIF} overload; external name 'fetch';
+    function fetch(resource: TJSObject; init: TJSObject): TJSPromise; overload; external name 'fetch';
+    function fetch(resource: TJSObject): TJSPromise; overload; external name 'fetch';
+    property isSecureContext : Boolean Read FisSecureContext;
+    property IDBFactory : TJSIDBFactory Read FIDBFactory;
+    property caches : TJSCacheStorage read fcaches;
+  end;
+
+
+
+
+(*
+
+
+// https://wicg.github.io/scheduling-apis/#ref-for-windoworworkerglobalscope-scheduler
+partial interface mixin WindowOrWorkerGlobalScope {
+  [Replaceable, Pref="dom.enable_web_task_scheduling", SameObject]
+  readonly attribute Scheduler scheduler;
+};
+*)
+
+implementation
+
+end.
+

+ 90 - 0
packages/rtl/webworker.pas

@@ -0,0 +1,90 @@
+unit webworker;
+
+{$mode ObjFPC}
+{$modeswitch externalclass}
+
+interface
+
+uses
+  JS, types, weborworker;
+
+Type
+
+  { TJSWorkerNavigator }
+
+  TJSWorkerNavigator = class external name 'WorkerNavigator' (TJSObject)
+  private
+    FhardwareConcurrency: Integer; external name 'hardwareConcurrency';
+    FLanguage: String; external name 'language';
+    FLanguages: TJSStringDynArray; external name 'languages';
+    FOnline: boolean; external name 'onLine';
+    FPlatform: string; external name 'platform';
+    FUserAgent: string; external name 'userAgent';
+  public
+    property language : String read FLanguage;
+    property languages : TJSStringDynArray read FLanguages;
+    property onLine : boolean read FOnline;
+    property platform : string read FPlatform;
+    property userAgent : string read FUserAgent;
+    property hardwareConcurrency : Integer Read FhardwareConcurrency;
+  end;
+
+  { TJSWorkerLocation }
+
+  TJSWorkerLocation = class external name 'WorkerLocation' (TJSObject)
+  Private
+    FHash: string;external name 'hash';
+    FHost: string;external name 'host';
+    FHostName: string;external name 'hostname';
+    FHRef: string; external name 'href';
+    FOrigin : string; external name 'origin';
+    FPathName: string;external name 'pathname';
+    FPort: string;external name 'port';
+    FProtocol: string;external name 'protocol';
+    FSearch: string;external name 'search';
+  Public
+    Property hash : string Read FHash;
+    Property host : string read FHost;
+    Property hostname : string read FHostName;
+    Property href : string read FHRef;
+    Property pathname : string Read FPathName;
+    Property port : string Read FPort;
+    Property protocol : string Read FProtocol;
+    Property search : string read FSearch;
+    property origin : string read FOrigin;
+  end;
+
+  { TJSWorkerGlobalScope }
+
+  TJSWorkerGlobalScope = class external name 'WorkerGlobalScope' (TWindowOrWorkerGlobalScope)
+  private
+    FConsole: TJSConsole; external name 'console';
+    FLocation: TJSWorkerLocation; external name 'location';
+    FNavigator: TJSWorkerNavigator; external name 'navigator';
+    FSelf : TJSWorkerGlobalScope external name 'self';
+  Public
+    procedure importScripts(path : string); varargs;
+    property Navigator: TJSWorkerNavigator read FNavigator;
+    property console : TJSConsole Read FConsole;
+    property location : TJSWorkerLocation Read FLocation;
+    Property Self_ : TJSWorkerGlobalScope Read FSelf;
+  end;
+
+Var
+  Self_ : TJSWorkerGlobalScope; external name 'self';
+  location : TJSWorkerLocation;
+  console : TJSConsole;
+  navigator : TJSWorkerNavigator;
+  serviceWorker : TJSServiceWorker;
+  caches : TJSCacheStorage;
+
+function fetch(resource: String; init: TJSObject): TJSPromise; overload; external name 'fetch';
+//function fetch(resource: String): TJSPromise; overload; external name 'fetch';
+function fetch(resource: String): TJSResponse; {$IFNDEF SkipAsync}async;{$ENDIF} overload; external name 'fetch';
+function fetch(resource: TJSObject; init: TJSObject): TJSPromise; overload; external name 'fetch';
+function fetch(resource: TJSObject): TJSPromise; overload; external name 'fetch';
+
+implementation
+
+end.
+