Browse Source

amd transport information output in .js

Herbert Vojčík 10 years ago
parent
commit
d2572b6c9a
3 changed files with 655 additions and 0 deletions
  1. 237 0
      js/Importer-Exporter.deploy.js
  2. 313 0
      js/Importer-Exporter.js
  3. 105 0
      st/Importer-Exporter.st

+ 237 - 0
js/Importer-Exporter.deploy.js

@@ -33,6 +33,24 @@ return self}, function($ctx1) {$ctx1.fill(self,"exportPackagePrologueOf:on:",{aP
 messageSends: ["nextPutAll:", "name", "lf"]}),
 smalltalk.AmdExporter.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportPackageTransportOf:on:",
+fn: function (aPackage,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.packages[");
+_st($1)._nextPutAll_(_st(_st(aPackage)._name())._asJavascript());
+_st($1)._nextPutAll_("].transport = ");
+_st($1)._nextPutAll_(_st(aPackage)._transportJson());
+_st($1)._nextPutAll_(";");
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageTransportOf:on:",{aPackage:aPackage,aStream:aStream},smalltalk.AmdExporter.klass)})},
+messageSends: ["nextPutAll:", "asJavascript", "name", "transportJson", "lf"]}),
+smalltalk.AmdExporter.klass);
+
 
 smalltalk.addClass('ChunkExporter', smalltalk.Object, [], 'Importer-Exporter');
 
@@ -385,6 +403,22 @@ smalltalk.ChunkParser.klass);
 
 smalltalk.addClass('Exporter', smalltalk.Object, [], 'Importer-Exporter');
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "amdRecipe",
+fn: function (){
+var self=this;
+var legacy;
+function $AmdExporter(){return smalltalk.AmdExporter||(typeof AmdExporter=="undefined"?nil:AmdExporter)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+legacy=self._recipe();
+$1=_st(_st(_st(legacy)._copyFrom_to_((1),(2))).__comma([_st($AmdExporter()).__minus_gt("exportPackageTransportOf:on:")])).__comma(_st(legacy)._copyFrom_to_((3),_st(legacy)._size()));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"amdRecipe",{legacy:legacy},smalltalk.Exporter.klass)})},
+messageSends: ["recipe", ",", "copyFrom:to:", "size", "->"]}),
+smalltalk.Exporter.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "classNameFor:",
@@ -839,6 +873,173 @@ messageSends: ["register:for:"]}),
 smalltalk.PackageHandler.klass);
 
 
+smalltalk.addClass('AmdPackageHandler', smalltalk.PackageHandler, [], 'Importer-Exporter');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitChannels",
+fn: function (){
+var self=this;
+function $Exporter(){return smalltalk.Exporter||(typeof Exporter=="undefined"?nil:Exporter)}
+function $StrippedExporter(){return smalltalk.StrippedExporter||(typeof StrippedExporter=="undefined"?nil:StrippedExporter)}
+function $ChunkExporter(){return smalltalk.ChunkExporter||(typeof ChunkExporter=="undefined"?nil:ChunkExporter)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=[(function(pkg){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st($Exporter())._amdRecipe()).__minus_gt(_st(_st(_st(_st(pkg)._commitPathJs()).__comma("/")).__comma(_st(pkg)._name())).__comma(".js"));
+}, function($ctx2) {$ctx2.fillBlock({pkg:pkg},$ctx1)})}),(function(pkg){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st($StrippedExporter())._amdRecipe()).__minus_gt(_st(_st(_st(_st(pkg)._commitPathJs()).__comma("/")).__comma(_st(pkg)._name())).__comma(".deploy.js"));
+}, function($ctx2) {$ctx2.fillBlock({pkg:pkg},$ctx1)})}),(function(pkg){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st($ChunkExporter())._recipe()).__minus_gt(_st(_st(_st(_st(pkg)._commitPathSt()).__comma("/")).__comma(_st(pkg)._name())).__comma(".st"));
+}, function($ctx2) {$ctx2.fillBlock({pkg:pkg},$ctx1)})})];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commitChannels",{},smalltalk.AmdPackageHandler)})},
+messageSends: ["->", ",", "name", "commitPathJs", "amdRecipe", "commitPathSt", "recipe"]}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitPathJsFor:",
+fn: function (aPackage){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._toUrl_(self._namespaceFor_(aPackage));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commitPathJsFor:",{aPackage:aPackage},smalltalk.AmdPackageHandler)})},
+messageSends: ["toUrl:", "namespaceFor:"]}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitPathStFor:",
+fn: function (aPackage){
+var self=this;
+var result;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+result=self._toUrl_(_st(self._namespaceFor_(aPackage)).__comma("/_source"));
+$2=_st(result)._match_("/_source$");
+if(smalltalk.assert($2)){
+$1=nil;
+} else {
+$1=result;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commitPathStFor:",{aPackage:aPackage,result:result},smalltalk.AmdPackageHandler)})},
+messageSends: ["toUrl:", ",", "namespaceFor:", "ifTrue:ifFalse:", "match:"]}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "namespaceFor:",
+fn: function (aPackage){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$4,$1;
+$2=_st(aPackage)._amdNamespace();
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=aPackage;
+_st($3)._amdNamespace_(_st(self._class())._defaultNamespace());
+$4=_st($3)._amdNamespace();
+$1=$4;
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"namespaceFor:",{aPackage:aPackage},smalltalk.AmdPackageHandler)})},
+messageSends: ["ifNil:", "amdNamespace:", "defaultNamespace", "class", "amdNamespace"]}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toUrl:",
+fn: function (aString){
+var self=this;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st($Smalltalk())._current())._at_("_amd_require");
+if(($receiver = $1) == nil || $receiver == undefined){
+self._error_("AMD loader not present");
+} else {
+var require;
+require=$receiver;
+$2=_st(_st(require)._basicAt_("toUrl"))._value_(aString);
+return $2;
+};
+return self}, function($ctx1) {$ctx1.fill(self,"toUrl:",{aString:aString},smalltalk.AmdPackageHandler)})},
+messageSends: ["ifNil:ifNotNil:", "error:", "value:", "basicAt:", "at:", "current"]}),
+smalltalk.AmdPackageHandler);
+
+
+smalltalk.AmdPackageHandler.klass.iVarNames = ['defaultNamespace'];
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitPathsFromLoader",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"commitPathsFromLoader",{},smalltalk.AmdPackageHandler.klass)})},
+messageSends: []}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "defaultNamespace",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@defaultNamespace"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("AMD default namespace not set.");
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"defaultNamespace",{},smalltalk.AmdPackageHandler.klass)})},
+messageSends: ["ifNil:", "error:"]}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "defaultNamespace:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@defaultNamespace"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"defaultNamespace:",{aString:aString},smalltalk.AmdPackageHandler.klass)})},
+messageSends: []}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.AmdPackageHandler.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
+self._registerFor_("amd");
+self._commitPathsFromLoader();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.AmdPackageHandler.klass)})},
+messageSends: ["initialize", "registerFor:", "commitPathsFromLoader"]}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "resetCommitPaths",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@defaultNamespace"]=nil;
+return self}, function($ctx1) {$ctx1.fill(self,"resetCommitPaths",{},smalltalk.AmdPackageHandler.klass)})},
+messageSends: []}),
+smalltalk.AmdPackageHandler.klass);
+
+
 smalltalk.addClass('LegacyPackageHandler', smalltalk.PackageHandler, [], 'Importer-Exporter');
 smalltalk.addMethod(
 smalltalk.method({
@@ -1179,6 +1380,31 @@ return $1;
 messageSends: ["asSet", "sortedClasses"]}),
 smalltalk.PluggableExporter.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "amdNamespace",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return (self.transport && self.transport.amdNamespace) || nil;
+return self}, function($ctx1) {$ctx1.fill(self,"amdNamespace",{},smalltalk.Package)})},
+messageSends: []}),
+smalltalk.Package);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "amdNamespace:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+
+	if (!self.transport) { self.transport = { type: 'amd' }; }
+	if (self.transport.type !== 'amd') { throw new Error('Package '+self._name()+' has transport type '+self.transport.type+', not "amd".'); }
+	self.transport.amdNamespace = aString;;
+return self}, function($ctx1) {$ctx1.fill(self,"amdNamespace:",{aString:aString},smalltalk.Package)})},
+messageSends: []}),
+smalltalk.Package);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "commit",
@@ -1292,6 +1518,17 @@ return $1;
 messageSends: ["for:", "transportType"]}),
 smalltalk.Package);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "transportJson",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return JSON.stringify(self.transport || null);;
+return self}, function($ctx1) {$ctx1.fill(self,"transportJson",{},smalltalk.Package)})},
+messageSends: []}),
+smalltalk.Package);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "transportType",

+ 313 - 0
js/Importer-Exporter.js

@@ -43,6 +43,29 @@ referencedClasses: []
 }),
 smalltalk.AmdExporter.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportPackageTransportOf:on:",
+category: 'exporting-output',
+fn: function (aPackage,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.packages[");
+_st($1)._nextPutAll_(_st(_st(aPackage)._name())._asJavascript());
+_st($1)._nextPutAll_("].transport = ");
+_st($1)._nextPutAll_(_st(aPackage)._transportJson());
+_st($1)._nextPutAll_(";");
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageTransportOf:on:",{aPackage:aPackage,aStream:aStream},smalltalk.AmdExporter.klass)})},
+args: ["aPackage", "aStream"],
+source: "exportPackageTransportOf: aPackage on: aStream\x0a\x09aStream\x0a\x09\x09nextPutAll: 'smalltalk.packages[';\x0a\x09\x09nextPutAll: aPackage name asJavascript;\x0a\x09\x09nextPutAll: '].transport = ';\x0a\x09\x09nextPutAll: aPackage transportJson;\x0a\x09\x09nextPutAll: ';';\x0a\x09\x09lf",
+messageSends: ["nextPutAll:", "asJavascript", "name", "transportJson", "lf"],
+referencedClasses: []
+}),
+smalltalk.AmdExporter.klass);
+
 
 smalltalk.addClass('ChunkExporter', smalltalk.Object, [], 'Importer-Exporter');
 smalltalk.ChunkExporter.comment="I am an exporter dedicated to outputting Amber source code in the classic Smalltalk chunk format.\x0a\x0aI do not output any compiled code.";
@@ -478,6 +501,27 @@ smalltalk.ChunkParser.klass);
 smalltalk.addClass('Exporter', smalltalk.Object, [], 'Importer-Exporter');
 smalltalk.Exporter.comment="I am responsible for outputting Amber code into a JavaScript string.\x0a\x0aThe generated output is enough to reconstruct the exported data, including Smalltalk source code and other metadata.\x0a\x0a## Use case\x0a\x0aI am typically used to save code outside of the Amber runtime (committing to disk, etc.).\x0a\x0a## API\x0a\x0aUse `#exportAll`, `#exportClass:` or `#exportPackage:` methods.";
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "amdRecipe",
+category: 'fileOut',
+fn: function (){
+var self=this;
+var legacy;
+function $AmdExporter(){return smalltalk.AmdExporter||(typeof AmdExporter=="undefined"?nil:AmdExporter)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+legacy=self._recipe();
+$1=_st(_st(_st(legacy)._copyFrom_to_((1),(2))).__comma([_st($AmdExporter()).__minus_gt("exportPackageTransportOf:on:")])).__comma(_st(legacy)._copyFrom_to_((3),_st(legacy)._size()));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"amdRecipe",{legacy:legacy},smalltalk.Exporter.klass)})},
+args: [],
+source: "amdRecipe\x0a\x09\x22Export a given package with amd transport type.\x22\x0a\x0a\x09| legacy |\x0a\x09legacy := self recipe.\x0a\x09^(legacy copyFrom: 1 to: 2),\x0a\x09{ AmdExporter -> #exportPackageTransportOf:on: },\x0a\x09(legacy copyFrom: 3 to: legacy size)",
+messageSends: ["recipe", ",", "copyFrom:to:", "size", "->"],
+referencedClasses: ["AmdExporter"]
+}),
+smalltalk.Exporter.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "classNameFor:",
@@ -1040,6 +1084,224 @@ referencedClasses: ["PackageHandler"]
 smalltalk.PackageHandler.klass);
 
 
+smalltalk.addClass('AmdPackageHandler', smalltalk.PackageHandler, [], 'Importer-Exporter');
+smalltalk.AmdPackageHandler.comment="I am responsible for handling package loading and committing.\x0d\x0a\x0d\x0aI should not be used directly. Instead, use the corresponding `Package` methods.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitChannels",
+category: 'committing',
+fn: function (){
+var self=this;
+function $Exporter(){return smalltalk.Exporter||(typeof Exporter=="undefined"?nil:Exporter)}
+function $StrippedExporter(){return smalltalk.StrippedExporter||(typeof StrippedExporter=="undefined"?nil:StrippedExporter)}
+function $ChunkExporter(){return smalltalk.ChunkExporter||(typeof ChunkExporter=="undefined"?nil:ChunkExporter)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=[(function(pkg){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st($Exporter())._amdRecipe()).__minus_gt(_st(_st(_st(_st(pkg)._commitPathJs()).__comma("/")).__comma(_st(pkg)._name())).__comma(".js"));
+}, function($ctx2) {$ctx2.fillBlock({pkg:pkg},$ctx1)})}),(function(pkg){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st($StrippedExporter())._amdRecipe()).__minus_gt(_st(_st(_st(_st(pkg)._commitPathJs()).__comma("/")).__comma(_st(pkg)._name())).__comma(".deploy.js"));
+}, function($ctx2) {$ctx2.fillBlock({pkg:pkg},$ctx1)})}),(function(pkg){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st($ChunkExporter())._recipe()).__minus_gt(_st(_st(_st(_st(pkg)._commitPathSt()).__comma("/")).__comma(_st(pkg)._name())).__comma(".st"));
+}, function($ctx2) {$ctx2.fillBlock({pkg:pkg},$ctx1)})})];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commitChannels",{},smalltalk.AmdPackageHandler)})},
+args: [],
+source: "commitChannels\x0a\x09^{ \x0a\x09\x09[ :pkg | Exporter amdRecipe -> (pkg commitPathJs, '/', pkg name, '.js') ].\x0a\x09\x09[ :pkg | StrippedExporter amdRecipe -> (pkg commitPathJs, '/', pkg name, '.deploy.js') ].\x0a\x09\x09[ :pkg | ChunkExporter recipe -> (pkg commitPathSt, '/', pkg name, '.st') ]\x0a\x09}",
+messageSends: ["->", ",", "name", "commitPathJs", "amdRecipe", "commitPathSt", "recipe"],
+referencedClasses: ["Exporter", "StrippedExporter", "ChunkExporter"]
+}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitPathJsFor:",
+category: 'committing',
+fn: function (aPackage){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._toUrl_(self._namespaceFor_(aPackage));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commitPathJsFor:",{aPackage:aPackage},smalltalk.AmdPackageHandler)})},
+args: ["aPackage"],
+source: "commitPathJsFor: aPackage\x0a\x09^self toUrl: (self namespaceFor: aPackage)",
+messageSends: ["toUrl:", "namespaceFor:"],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitPathStFor:",
+category: 'committing',
+fn: function (aPackage){
+var self=this;
+var result;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+result=self._toUrl_(_st(self._namespaceFor_(aPackage)).__comma("/_source"));
+$2=_st(result)._match_("/_source$");
+if(smalltalk.assert($2)){
+$1=nil;
+} else {
+$1=result;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commitPathStFor:",{aPackage:aPackage,result:result},smalltalk.AmdPackageHandler)})},
+args: ["aPackage"],
+source: "commitPathStFor: aPackage\x0a\x09| result |\x0a\x09result := self toUrl: (self namespaceFor: aPackage), '/_source'.\x0a\x09^ (result match: '/_source$') ifTrue: [ nil ] ifFalse: [ result ]",
+messageSends: ["toUrl:", ",", "namespaceFor:", "ifTrue:ifFalse:", "match:"],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "namespaceFor:",
+category: 'committing',
+fn: function (aPackage){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$4,$1;
+$2=_st(aPackage)._amdNamespace();
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=aPackage;
+_st($3)._amdNamespace_(_st(self._class())._defaultNamespace());
+$4=_st($3)._amdNamespace();
+$1=$4;
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"namespaceFor:",{aPackage:aPackage},smalltalk.AmdPackageHandler)})},
+args: ["aPackage"],
+source: "namespaceFor: aPackage\x0a\x09^aPackage amdNamespace\x0a\x09\x09ifNil: [ aPackage amdNamespace: self class defaultNamespace; amdNamespace ]",
+messageSends: ["ifNil:", "amdNamespace:", "defaultNamespace", "class", "amdNamespace"],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "toUrl:",
+category: 'private',
+fn: function (aString){
+var self=this;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st($Smalltalk())._current())._at_("_amd_require");
+if(($receiver = $1) == nil || $receiver == undefined){
+self._error_("AMD loader not present");
+} else {
+var require;
+require=$receiver;
+$2=_st(_st(require)._basicAt_("toUrl"))._value_(aString);
+return $2;
+};
+return self}, function($ctx1) {$ctx1.fill(self,"toUrl:",{aString:aString},smalltalk.AmdPackageHandler)})},
+args: ["aString"],
+source: "toUrl: aString\x0a\x09(Smalltalk current at: '_amd_require')\x0a\x09\x09ifNil: [ self error: 'AMD loader not present' ]\x0a\x09\x09ifNotNil: [ :require | ^(require basicAt: 'toUrl') value: aString ]",
+messageSends: ["ifNil:ifNotNil:", "error:", "value:", "basicAt:", "at:", "current"],
+referencedClasses: ["Smalltalk"]
+}),
+smalltalk.AmdPackageHandler);
+
+
+smalltalk.AmdPackageHandler.klass.iVarNames = ['defaultNamespace'];
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commitPathsFromLoader",
+category: 'commit paths',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"commitPathsFromLoader",{},smalltalk.AmdPackageHandler.klass)})},
+args: [],
+source: "commitPathsFromLoader\x0a\x09\x22TODO\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "defaultNamespace",
+category: 'commit paths',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@defaultNamespace"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("AMD default namespace not set.");
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"defaultNamespace",{},smalltalk.AmdPackageHandler.klass)})},
+args: [],
+source: "defaultNamespace\x0a\x09^ defaultNamespace ifNil: [ self error: 'AMD default namespace not set.' ]",
+messageSends: ["ifNil:", "error:"],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "defaultNamespace:",
+category: 'commit paths',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@defaultNamespace"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"defaultNamespace:",{aString:aString},smalltalk.AmdPackageHandler.klass)})},
+args: ["aString"],
+source: "defaultNamespace: aString\x0a\x09defaultNamespace := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.AmdPackageHandler.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
+self._registerFor_("amd");
+self._commitPathsFromLoader();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.AmdPackageHandler.klass)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09self registerFor: 'amd'.\x0a\x09self commitPathsFromLoader",
+messageSends: ["initialize", "registerFor:", "commitPathsFromLoader"],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "resetCommitPaths",
+category: 'commit paths',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@defaultNamespace"]=nil;
+return self}, function($ctx1) {$ctx1.fill(self,"resetCommitPaths",{},smalltalk.AmdPackageHandler.klass)})},
+args: [],
+source: "resetCommitPaths\x0a\x09defaultNamespace := nil",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AmdPackageHandler.klass);
+
+
 smalltalk.addClass('LegacyPackageHandler', smalltalk.PackageHandler, [], 'Importer-Exporter');
 smalltalk.LegacyPackageHandler.comment="I am responsible for handling package loading and committing.\x0d\x0a\x0d\x0aI should not be used directly. Instead, use the corresponding `Package` methods.";
 smalltalk.addMethod(
@@ -1486,6 +1748,41 @@ referencedClasses: []
 }),
 smalltalk.PluggableExporter.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "amdNamespace",
+category: '*Importer-Exporter',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return (self.transport && self.transport.amdNamespace) || nil;
+return self}, function($ctx1) {$ctx1.fill(self,"amdNamespace",{},smalltalk.Package)})},
+args: [],
+source: "amdNamespace\x0a<return (self.transport && self.transport.amdNamespace) || nil>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Package);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "amdNamespace:",
+category: '*Importer-Exporter',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+
+	if (!self.transport) { self.transport = { type: 'amd' }; }
+	if (self.transport.type !== 'amd') { throw new Error('Package '+self._name()+' has transport type '+self.transport.type+', not "amd".'); }
+	self.transport.amdNamespace = aString;;
+return self}, function($ctx1) {$ctx1.fill(self,"amdNamespace:",{aString:aString},smalltalk.Package)})},
+args: ["aString"],
+source: "amdNamespace: aString\x0a<\x0a\x09if (!self.transport) { self.transport = { type: 'amd' }; }\x0a\x09if (self.transport.type !== 'amd') { throw new Error('Package '+self._name()+' has transport type '+self.transport.type+', not \x22amd\x22.'); }\x0a\x09self.transport.amdNamespace = aString;\x0a>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Package);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "commit",
@@ -1629,6 +1926,22 @@ referencedClasses: ["PackageHandler"]
 }),
 smalltalk.Package);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "transportJson",
+category: '*Importer-Exporter',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return JSON.stringify(self.transport || null);;
+return self}, function($ctx1) {$ctx1.fill(self,"transportJson",{},smalltalk.Package)})},
+args: [],
+source: "transportJson\x0a\x09<return JSON.stringify(self.transport || null);>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Package);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "transportType",

+ 105 - 0
st/Importer-Exporter.st

@@ -17,6 +17,16 @@ exportPackagePrologueOf: aPackage on: aStream
 		nextPutAll: aPackage name;
 		nextPutAll: '", ["amber_vm/smalltalk","amber_vm/nil","amber_vm/_st"], function(smalltalk,nil,_st){';
 		lf
+!
+
+exportPackageTransportOf: aPackage on: aStream
+	aStream
+		nextPutAll: 'smalltalk.packages[';
+		nextPutAll: aPackage name asJavascript;
+		nextPutAll: '].transport = ';
+		nextPutAll: aPackage transportJson;
+		nextPutAll: ';';
+		lf
 ! !
 
 Object subclass: #ChunkExporter
@@ -345,6 +355,16 @@ exportPackagePrologueOf: aPackage on: aStream
 
 !Exporter class methodsFor: 'fileOut'!
 
+amdRecipe
+	"Export a given package with amd transport type."
+
+	| legacy |
+	legacy := self recipe.
+	^(legacy copyFrom: 1 to: 2),
+	{ AmdExporter -> #exportPackageTransportOf:on: },
+	(legacy copyFrom: 3 to: legacy size)
+!
+
 recipe
 	"Export a given package."
 
@@ -506,6 +526,75 @@ registerFor: aString
 	PackageHandler register: self for: aString
 ! !
 
+PackageHandler subclass: #AmdPackageHandler
+	instanceVariableNames: ''
+	package: 'Importer-Exporter'!
+!AmdPackageHandler commentStamp!
+I am responsible for handling package loading and committing.
+
+I should not be used directly. Instead, use the corresponding `Package` methods.!
+
+!AmdPackageHandler methodsFor: 'committing'!
+
+commitChannels
+	^{ 
+		[ :pkg | Exporter amdRecipe -> (pkg commitPathJs, '/', pkg name, '.js') ].
+		[ :pkg | StrippedExporter amdRecipe -> (pkg commitPathJs, '/', pkg name, '.deploy.js') ].
+		[ :pkg | ChunkExporter recipe -> (pkg commitPathSt, '/', pkg name, '.st') ]
+	}
+!
+
+commitPathJsFor: aPackage
+	^self toUrl: (self namespaceFor: aPackage)
+!
+
+commitPathStFor: aPackage
+	| result |
+	result := self toUrl: (self namespaceFor: aPackage), '/_source'.
+	^ (result match: '/_source$') ifTrue: [ nil ] ifFalse: [ result ]
+!
+
+namespaceFor: aPackage
+	^aPackage amdNamespace
+		ifNil: [ aPackage amdNamespace: self class defaultNamespace; amdNamespace ]
+! !
+
+!AmdPackageHandler methodsFor: 'private'!
+
+toUrl: aString
+	(Smalltalk current at: '_amd_require')
+		ifNil: [ self error: 'AMD loader not present' ]
+		ifNotNil: [ :require | ^(require basicAt: 'toUrl') value: aString ]
+! !
+
+AmdPackageHandler class instanceVariableNames: 'defaultNamespace'!
+
+!AmdPackageHandler class methodsFor: 'commit paths'!
+
+commitPathsFromLoader
+	"TODO"
+!
+
+defaultNamespace
+	^ defaultNamespace ifNil: [ self error: 'AMD default namespace not set.' ]
+!
+
+defaultNamespace: aString
+	defaultNamespace := aString
+!
+
+resetCommitPaths
+	defaultNamespace := nil
+! !
+
+!AmdPackageHandler class methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	self registerFor: 'amd'.
+	self commitPathsFromLoader
+! !
+
 PackageHandler subclass: #LegacyPackageHandler
 	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
@@ -668,6 +757,18 @@ ownClassesOfPackage: package
 
 !Package methodsFor: '*Importer-Exporter'!
 
+amdNamespace
+<return (self.transport && self.transport.amdNamespace) || nil>
+!
+
+amdNamespace: aString
+<
+	if (!!self.transport) { self.transport = { type: 'amd' }; }
+	if (self.transport.type !!== 'amd') { throw new Error('Package '+self._name()+' has transport type '+self.transport.type+', not "amd".'); }
+	self.transport.amdNamespace = aString;
+>
+!
+
 commit
 	^ self transport commit: self
 !
@@ -692,6 +793,10 @@ transport
 	^ PackageHandler for: self transportType
 !
 
+transportJson
+	<return JSON.stringify(self.transport || null);>
+!
+
 transportType
 	<return (self.transport && self.transport.type) || 'unknown';>
 ! !